Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Inner join

Estas en el tema de Inner join en el foro de Mysql en Foros del Web. hola que tal, de vuelta por estos pagos.. esta vez necesito consejo si usar mi script o cambiarlo. actualmente estoy usando un esquema como este: ...
  #1 (permalink)  
Antiguo 16/11/2008, 07:10
 
Fecha de Ingreso: noviembre-2008
Mensajes: 21
Antigüedad: 15 años, 5 meses
Puntos: 1
Inner join

hola que tal, de vuelta por estos pagos.. esta vez necesito consejo si usar mi script o cambiarlo.

actualmente estoy usando un esquema como este:

tengo 4 tablas

[tabla1]
id nombre
1 oscar
2 ricardo

[tabla2]
id ciudad
1 paris
2 chicago

[tabla3]
id codigo
1 1300
2 1250

[Link]
id nombre ciudad codigo
1 2 1 1
2 1 1 1

3 tablas con datos y 1 tabla con la referencia de las mismas

$query = "SELECT tabla1.nombre, tabla2.ciudad, tabla3.codigo
FROM tabla1, tabla2, tabla3
WHERE
link.nombre = tabla1.id
AND
link.ciudad = tabla2.id
AND
link.codigo = tabla3.id"

es preferible usar INNER JOIN? como seria en este caso?

muchas gracias.
  #2 (permalink)  
Antiguo 16/11/2008, 08:33
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Inner join

Cuando usas un esquema del tipo:
Código sql:
Ver original
  1. SELECT tabla1.nombre, tabla2.ciudad, tabla3.codigo
  2. FROM tabla1, tabla2, tabla3
  3. WHERE
  4. link.nombre = tabla1.id
  5. AND
  6. link.ciudad = tabla2.id
  7. AND
  8. link.codigo = tabla3.id"

MySQL no puede optimizarlo de ninguna forma porque no sabe inicialmente cuátos registros devolverá cada condición del WHERE. Por eso es preferible usar al WHERE como selector final de algo que ya se haya depurado suficientemente. Allí es donde entra el JOIN y en el caso el INNER JOIN.
Piensalo de esta forma: Si lee en forma secuencial, y no existe ningún índice definido con los tres campos como clave, entonces recuperará todos los registros de la primera condición, luego eliminará de ese conjunto los de la segunda condición y finalmente los de la tercera. Cada comparación es secuencial, con lo que la consulta resulta muy ineficiente.
El INNER JOIN lee por coincidencia de los tres campos al mismo tiempo, en tanto los hagas encadenando el JOIN de forma correcta:

Código sql:
Ver original
  1. SELECT T1.nombre, T2.ciudad, T3.codigo
  2. FROM link L INNER JOIN tabla1 T1 ON L.nombre = T1.id
  3.    INNER JOIN tabla2 T2 ON L.ciudad = T2.id
  4.    INNER JOIN tabla3 T3 ON L.codigo  = T3.id

Dos detalles:
1. SI la tabla link usa los las tres PK para crear el registro como FK y cada registros es único, el campo ID de esa tabla es innecesario, ya que la unicidad esta dada por las tres (relación 1 a N). En todo caso tomas los tres campos y los defines como PK y listo.
2. No es buena costumbre poner los ID numéricos que sean claves con el mismo nombre en diferentes tablas. Termina siendo difícil distinguir a cuál te refieres al codificar. Si te equivocas de tabla dependiente no lo sabrás hasta que los resultados no sean los esperados. Lo que suele hacerse es darle en sufijo "ID" al nombre del campo, pero el prefijo haciendo referencia a la tabla; de esta forma quedaría: LINK_ID, CIUDAD_ID, CODIGO_ID, NOMBRE_ID. Es la forma más mnemotécnica de escribir los nombres. Lo verás si analizas modelos de bases de datos estandarizadas (es un habito de la programación, como poner o, v, o t delante de las variables en POO).
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 16/11/2008, 09:26
 
Fecha de Ingreso: noviembre-2008
Mensajes: 21
Antigüedad: 15 años, 5 meses
Puntos: 1
Respuesta: Inner join

me anda a medias, cuando lo pongo asi, me tira el index de los resultados como resultados ejemplo

nombre: 1
ciudad : 2
codigo: 3

y no el valor que tendria q tener el nombre 1 ejemplo oscar

que es lo q me falta?

Última edición por r4ilgun; 16/11/2008 a las 11:15
  #4 (permalink)  
Antiguo 16/11/2008, 11:23
 
Fecha de Ingreso: junio-2004
Mensajes: 266
Antigüedad: 19 años, 10 meses
Puntos: 8
Respuesta: Inner join

La respuesta que te han dado parece correcta, ¿puedes especificar exactamente que campos quieres sacar de cada tabla?
__________________
WebSenior
  #5 (permalink)  
Antiguo 16/11/2008, 12:33
 
Fecha de Ingreso: noviembre-2008
Mensajes: 21
Antigüedad: 15 años, 5 meses
Puntos: 1
Respuesta: Inner join

[tabla1]
id nombre
1 oscar
2 ricardo

[tabla2]
id ciudad
1 paris
2 chicago

[tabla3]
id codigo
1 1300
2 1250

[Link]
id nombre ciudad codigo
1 2 2 2
2 1 1 1

ahora, necesito realizar una busqueda de nombre, ciudad y codigo
si busco "oscar" se fija en la tabla "link" la referencia numerica del nombre y lo busca en la tabla1 asimismo la referencia de ciudad y lo busca en tabla2 y la de codigo y lo busca en tabla3
  #6 (permalink)  
Antiguo 16/11/2008, 12:41
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Inner join

Postea la sentencia completa, tal y como la estás usando.
El modelo que te puse debería responder correctamente, por cuanto son tres campos seleccionados, tal como pusiste tu ejemplo. La única distinción es que se indican las tablas por ALIAS y no por nombre (para acortar la escritura), lo que no debería generar errores.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 16/11/2008, 13:06
 
Fecha de Ingreso: noviembre-2008
Mensajes: 21
Antigüedad: 15 años, 5 meses
Puntos: 1
Respuesta: Inner join

Código sql:
Ver original
  1. $query=
  2. "SELECT *
  3. FROM link
  4. INNER JOIN name ON link.name = name.id
  5. INNER JOIN director ON link.director = director.id
  6. INNER JOIN genre ON link.genre = genre.id
  7. INNER JOIN cast ON link.cast = cast.id
  8. INNER JOIN date ON link.date = date.id
  9. INNER JOIN url ON link.url = url.id"
  10. OR die (mysql_error());
  11. $result = mysql_query($query)
  12. OR die (mysql_error());
  13. $num=mysql_num_rows($result);

$i=0;
while ($i < $num)
{

$name=mysql_result($result,$i,"link.name");
$date=mysql_result($result,$i,"link.date");
$genre=mysql_result($result,$i,"link.genre");
$director=mysql_result($result,$i,"link.director") ;
$cast=mysql_result($result,$i,"link.cast");
$url=mysql_result($result,$i,"link.url");

echo "Movie: $name";
echo "<br>";
echo "Genre: $genre";
echo "<br>";
echo "Director: $director";
echo "<br>";
echo "Cast: $cast";
echo "<br>";
echo "Url: $url";
echo "<br>";
echo "Date: $date";
echo "<br>";
echo "<br>";

$i++;
}

es para una base de datos con la info de las pelis para mi colleccion

PD: ahora que me pongo a pensar capaz esta mal la variable del row no?

a esto despues le agrego un _get para el buscador

$search = empty($_GET['q'])? die ("<center>ERROR: Please enter a search criteria.</center>") : mysql_real_escape_string($_GET['q']);
  #8 (permalink)  
Antiguo 16/11/2008, 13:27
 
Fecha de Ingreso: junio-2004
Mensajes: 266
Antigüedad: 19 años, 10 meses
Puntos: 8
Respuesta: Inner join

Pero si es una búsqueda... ¿Donde le pasas los parametros a la query?
__________________
WebSenior
  #9 (permalink)  
Antiguo 16/11/2008, 13:38
 
Fecha de Ingreso: noviembre-2008
Mensajes: 21
Antigüedad: 15 años, 5 meses
Puntos: 1
Respuesta: Inner join

calculo que con un where link.name like '%$search%'"

PD: todavia no es una busqueda, ahora tendria q mostrar todos los rows. hasta que no me ande eso
no voy a andar complicandomela.
  #10 (permalink)  
Antiguo 16/11/2008, 14:56
 
Fecha de Ingreso: junio-2004
Mensajes: 266
Antigüedad: 19 años, 10 meses
Puntos: 8
Respuesta: Inner join

Ah, vale, bueno entonces te explico como mostrar resultados de una query:

Código:
$query  = "select * from link...";
$result = mysql_query($query);

while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
    echo "Name: ". $row['nombre'];
}
__________________
WebSenior
  #11 (permalink)  
Antiguo 17/11/2008, 06:28
 
Fecha de Ingreso: noviembre-2008
Mensajes: 21
Antigüedad: 15 años, 5 meses
Puntos: 1
Respuesta: Inner join

Cita:
Iniciado por kurroman Ver Mensaje
Ah, vale, bueno entonces te explico como mostrar resultados de una query:

Código:
$query  = "select * from link...";
$result = mysql_query($query);

while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
    echo "Name: ". $row['nombre'];
}
nono, pense q habias entendido que eso ya lo sabia :/.. el tema es el inner join con el criterio de otra tabla = toy algo molesto y tengo q hacer otras cosas tmb.. lo voy a dejar para mas adelante.

gracias igualmente.
  #12 (permalink)  
Antiguo 17/11/2008, 07:20
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Inner join

Tres detalles:
1. No uses una consulta del tipo "SELECT * FROM ...", no sólo porque es muy ineficiente (es la peor de todas las formas), sino porque te traerá campos que realmente no estás usando al final. En este caso te trae no sólo los datos sino todos los ID de todas las tablas involucradas.
¿Realmente vas a usar TODO eso?

2. la consulta:
Código sql:
Ver original
  1. SELECT *
  2. FROM link
  3. INNER JOIN name ON link.name = name.id
  4. INNER JOIN director ON link.director = director.id
  5. INNER JOIN genre ON link.genre = genre.id
  6. INNER JOIN CAST ON link.CAST = CAST.id
  7. INNER JOIN DATE ON link.DATE = DATE.id
  8. INNER JOIN url ON link.url = url.id;
tiene además el problema de usar los mismos nombres para los campos que para las tablas... lo que con MySQL puede dar errores, resultados inesperados o no deseados. Ese puede ser el caso. Por esa razón te recomendaba usar los nombres de los campos como "NAME_ID", por ejemplo.
Fuera de eso, el código debería estar devolviendote correctamente los registros. No hay razón para que falle.

3. Finalmente, por favor, es una regla en este foro y en todos los foros en general, la de no poner código que no sea específico del foro. Para eso existen los foros de PHP, .NET, ASP, JAVA y demás.
Cuando escribes PHP mezclado con el SQL, el SQL se ve "sucio", y no es posible saber al final si el error está en el SQL o en el PHP y de esa forma se nos dificulta ver el problema y poder contestarte.
Entiendo que te resulte fácil copiar y pegar, pero los que somos DBA no programamos aplicaciones y no nos dedicamos a leer códigos que no sea SQL, en cualquiera de sus formas. Ten en cuenta eso.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #13 (permalink)  
Antiguo 19/11/2008, 07:14
 
Fecha de Ingreso: noviembre-2008
Mensajes: 21
Antigüedad: 15 años, 5 meses
Puntos: 1
Respuesta: Inner join

al final despues de despejarme un poco y volver a retomar; gracias a tus esfuerzos, logre que me funcione como queria; te lo agradesco mucho "gnzsoloyo"
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 06:59.