Cuidado con utilizar y mezclar las cláusulas INNER JOIN / LEFT JOIN en MySQL con una lista de tablas en el FROM. Por ejemplo, un tipico SELECT:
1 2 3 4 | SELECT * FROM tabla1 t1, tabla2 t2 LEFT JOIN tabla3 t3 ON t3.id = t1.id WHERE t1.id = t2.id |
Funcionaba bien hasta la versión 5.0.12 de MySQL. A partir de la versión 5.0.12, ha cambiado la precedencia de los operadores “coma” (,) y JOIN, de tal forma que se produce un error “Unknown column ‘t1.id’ in ‘on clause’”. Esto rompe de manera definitiva algunos programas, osCommerce por ejemplo.
La solución es poner paréntesis para forzar la precedencia de los operadores “coma” y JOIN, o también cambiar la coma por un INNER JOIN, de tal forma que el anterior query quedaría de la siguiente forma:
1 2 3 4 | SELECT * FROM tabla1 t1 INNER JOIN tabla2 t2 ON t2.id = t1.id LEFT JOIN tabla3 t3 ON t3.id = t1.id |
O también:
1 2 3 4 | SELECT * FROM (tabla1 t1, tabla2 t2) LEFT JOIN tabla3 t3 ON t3.id = t1.id WHERE t1.id = t2.id |
Personalmente prefiero la primera, considero que es mucho más correcto ya que todas las uniones de las tablas se hacen directamente en cláusulas ON dejando el WHERE libre para las restricciones de los datos, no las uniones.
Otra solución que hay es:
SELECT * FROM tabla t2, tabla t1 LEFT JOIN tabla3 t3 ON t3.id = t1.id WHERE t1.id = t2.id
Aunque como bien dices, es mas limpia tu primera alternativa. Otro mundo interesante es el del OUTER JOIN.
PD: Saludos!!!!!
Jorge, gracias por comentar!
¿Seguro que cambiando el orden en el SELECT de las tablas t1 y t2 se altera la precedencia y funciona? En la documentación pone claramente que es problema de precedencia y las dos soluciones que dan son o utilizar paréntesis o usar cláusulas INNER/OUTER/LEFT JOIN. Tengo que probar más detenidamente estas cosas, pero sabes que me gusta usar soluciones definitivas.
De echo este problema me lo encontré cuando en lmental cambiamos de servidor con mysql 4 a mysq 5, que habia algunas webs (como la de ibernon) que no funcionaban y era por culpa de eso. Al cambiar el orden de las tablas empezó a funcionar, lo que si es cierto que no deja de ser un apaño, y es mejor usar los inners en vez de referenciar.
Lo del outer lo probé una vez que se me planteó el problema de, sacar elementos de una tabla que no estén referenciados en otra tabla.
Que sepas que sales octavo en google por “orden mysql left join”. Qué cosas…
@Josal, ¿Sólo el octavo? Yo no me conformaría con menos de la primera posición…