coge la información y corre

Múltiples join y solución al encadenar LEFT JOINS

5 de noviembre del 2009 Escrito por Alex Barros

Desde que publiqué el artículo de Inner Join para unir tablas y más especialmente el de Explicación visual de los SQL Join – Unir tablas con SQL me han consultado en muchos comentarios cómo hacer múltiples JOIN en una sóla consulta.

Hasta hoy no lo había necesitado, y nunca supe contestar. Hasta hoy.

Encadenar Joins es tan simple como ponerlos uno a continuación de otro.
ejemplo:

  1. SELECT A.*, B.*, C.id FROM tabla_a A
  2. INNER JOIN tabla_b B ON A.id = B.foo
  3. LEFT JOIN tabla_c C ON A.id = C.bar

Y así sucesivamente. Puedes tener tantos joins como necesites, y si es necesario jugar con los paréntesis para cambiar la preferencia (por defecto MySQL lee de izquierda a derecha).

Pero una vez esto aclarado, me he encontrado con un problema. Lo que yo quería hacer es una serie de LEFT JOINs para consultar en una serie de tablas la cantidad (COUNT()) de registros de otras tablas que estaban asociados a la clave primaria de una tabla principal.

En mi caso concreto, tengo una serie de Rutas de bicicleta en una tabla, y en otras tablas satélite tengo almacenados los comentarios asociados a la ruta, las votaciones, los archivos adjuntos, etc… de modo que haciendo un COUNT en estas tablas para cada una de las claves primarias de la principal (Rutas) me saldría la cantidad asociada.

Así que hice algo como esto:

  1. SELECT R.*, COUNT(C.id) comments, COUNT(S.id) saved, COUNT(V.id) votes, COUNT(P.id) photos, U.name owner, U.mail, U.about, U.image avatar, U.authority
  2.  
  3. FROM geo_routes R
  4. LEFT JOIN geo_comments_routes C ON R.id = C.cid
  5. LEFT JOIN geo_saved S ON R.id = S.route
  6. LEFT JOIN geo_votes V ON R.id = V.route
  7. LEFT JOIN geo_photos P ON R.id = P.route
  8. LEFT JOIN geo_users U ON U.id = R.property
  9.  
  10. GROUP BY R.id

Pero esta consulta no daba valores correctos, sinó que en estos campos COUNT aparecía generalmente el mismo número replicado.

La solución es usar la cláusula DISTINCT en los COUNT, ya que en cada uno de los LEFT JOIN se están asociando muchos campos a cada registro de la tabla principal, y si no especificas el que te interesa cuántos DISTINTOS hay (y no sólo cuántos hay) te hincha la cifra o simplemente te la altera.

De modo que mi consulta ha quedado así:

  1. SELECT R.*, COUNT(DISTINCT C.id) comments, COUNT(DISTINCT S.id) saved, COUNT(DISTINCT V.id) votes, COUNT(DISTINCT P.id) photos, U.name owner, U.mail, U.about, U.image avatar, U.authority
  2.  
  3. FROM geo_routes R
  4. LEFT JOIN geo_comments_routes C ON R.id = C.cid
  5. LEFT JOIN geo_saved S ON R.id = S.route
  6. LEFT JOIN geo_votes V ON R.id = V.route
  7. LEFT JOIN geo_photos P ON R.id = P.route
  8. LEFT JOIN geo_users U ON U.id = R.property
  9.  
  10. GROUP BY R.id

Después he asociado a esta consulta una Vista, para poder tratarla como si fuera una tabla con esos campos ya incluidos.

Espero que estos consejos os puedan servir de mucho! A mi me ha costado mucho dar con las respuestas.

Categorias: Boozox |

A que no te atreves a escribir un comentario diciendo lo que piensas!

Hay 17 comentarios, pero nos falta el tuyo

Bloodsucker Ha dicho:

¡aiiiii!, la asignatura de Bases de Datos que útil es :P

Cada día se aprende más que el anterior

Boozox » Explicación visual de los SQL Join - Unir tablas con SQL Ha dicho:

[...] Ver también: Hacer Múltiples Join en una sola Sentencia [...]

willy Ha dicho:

Muchas gracias por tus aportaciones, me estan ayudando mucho con el comienzo de SQL.
Tengo una duda con el concepto de unir varios left outer join y quería preguntarte.

Entiendo que cada vez que unes un left outer join estas haciendo referencia a los resultados del anterior left outer join, no?

En la sentencia que pones como ejemplo trae todos los registros de la tabla geo_routes con coincidencia R.id=C.cid, el segundo left join trae todos los registros del primer left mas las coincidencias con la tabla geo_saved y la clausula R.id=S.route

Es correcta esta interpretación??

Muchas gracias

Alex Barros Ha dicho:

Efectivamente, la interpretación es correcta.

Como digo en este post, SQL lee de izquierda a derecha, a no ser que alteres el orden con paréntesis.

De modo que une la primera con la segunda, y el resultado con la tercera, etcétera.

gabriel Ha dicho:

Hola yo necesito enlazar diferentes campos de mas de 5 tablas diferentes, en la cual algunas tablas no tienen ningun campo en comun y por eso no puedo enlazarlas me pueden ayudar.

Tablas campo
usuario nombre y edad
datos nombre y ciudad y sexo
trabajo direccion y oficina
unicos peso y altura

Yopi Ha dicho:

Mil GRACIAS!!

Comprendido!

Te acabas de ganar un lector :)

Andres Ha dicho:

Gracias ya me imagino cuanto te costo yo tambien estaba en problemas con esto de los left join pero con tu ayuda lo conseguí

Vitax Ha dicho:

Excelentes aportaciones!!

La forma visual me ha ayudado enormemente cuando tengo dudas.

Mil gracias!!

Boozox » INNER JOIN para unir Tablas Ha dicho:

[...] Ver también: Explicación visual de los SQL Join Ver también: Hacer Múltiples Join en una sola Sentencia [...]

LUIS Ha dicho:

antes que nada me ha servido esta pagina y tengo un problema tengo una tabla principal con campos per1, per2, per3 y otra tabla con concepto como puedo unir estas dos tablas per1 con su concento, per2 con su concepto, per3 con su concepto, en las dos tablas tienen codigo pero quiero visualizar su concepto de cada una, gracias de antemano.

Walter Ha dicho:

Hola
Este tuto parece muy interesante solo que no he entendido el ejemplo.
Para quienes recién comienza a incursionar en estos temas, seria genial que este tuto tenga un mejor ejemplo, mas comprensible, como lo es tu otro tuto de Explicación visual de los SQL Join. Donde se muestran las tablas, etc.

Entiendo que hacer un tuto desarrollado mas gráficamente lleva mas tiempo su elaboración, aun así es mucho mas comprensible para nosotros, quienes te lo valorarían muchísimo sin lugar a dudas ya que es un tema muy interesante.

Espero que tomes a bien mi sugerencia.

Volveré al sitio por si acaso haz desarrollado este mismo tuto con mas ejemplo.

Desde ya te agradezco por tu buena voluntad en hacer estos tutos.

Salute.

Alex Barros Ha dicho:

@Walter. Este post trata de joins encadenados. Si entendiste lo que eran los joins y cómo funcionaban en el anterior post, no te debería costar mucho entender en qué consisten los Joins encadenados.

Considera que, en lugar de querer unir dos tablas [a - b] quieres encadenar más [[a - b] – c]

John Ha dicho:

Buena explicación, ayudas mucho a la gente que apenas esta empezando en el cuento. Sigue asi!.

saulo123 Ha dicho:

Buenos dias espero esten bien necesito una gran favor, estoy tratando de hacer un cruce (osea unir 2 tablas pero solo me deben quedar, valores no repetidos) las 2 tablas son “pinst1 y pinst2 ” para actualizarlas, de las cuales solo me debe quedar una sola con los valores actualizados, les agradezco de antemano…

Amelia Maddox Ha dicho:

Gracias ya me imagino cuanto te costo yo tambien estaba en problemas con esto de los left join pero con tu ayuda lo conseguí

Michele Foley Ha dicho:

Hola Este tuto parece muy interesante solo que no he entendido el ejemplo. Para quienes recién comienza a incursionar en estos temas, seria genial que este tuto tenga un mejor ejemplo, mas comprensible, como lo es tu otro tuto de Explicación visual de los SQL Join. Donde se muestran las tablas, etc. Entiendo que hacer un tuto desarrollado mas gráficamente lleva mas tiempo su elaboración, aun así es mucho mas comprensible para nosotros, quienes te lo valorarían muchísimo sin lugar a dudas ya que es un tema muy interesante. Espero que tomes a bien mi sugerencia. Volveré al sitio por si acaso haz desarrollado este mismo tuto con mas ejemplo. Desde ya te agradezco por tu buena voluntad en hacer estos tutos. Salute.

SaRa... Ha dicho:

Un favor recien soy aprendiz sobre el inner join un clase…

del.icio.us meneame.net RSS

Search:

Bicivalencia Localiza las estaciones de Valenbisi, servicio público de bicicletas en Valencia, España. Ver más Gpsia Descubre y comparte rutas por todo el mundo, tomadas con GPS. Ver más Imaset Edita tus imágenes de Wordpress con este sencillo plugin. Ver más

¡Mi música es tuya!

Digo yo que...

Mis fotos de Flickr

Entradas recientes

Meta:

Respeta el copyleft

,