Por simplicidad, suponga que todos los campos relevantes son NOT NULL
.
Tu puedes hacer:
SELECT
table1.this, table2.that, table2.somethingelse
FROM
table1, table2
WHERE
table1.foreignkey = table2.primarykey
AND (some other conditions)
Si no:
SELECT
table1.this, table2.that, table2.somethingelse
FROM
table1 INNER JOIN table2
ON table1.foreignkey = table2.primarykey
WHERE
(some other conditions)
¿Estos dos funcionan de la misma manera MySQL
?
sql
mysql
join
inner-join
JCCyC
fuente
fuente
Respuestas:
INNER JOIN
es la sintaxis ANSI que debes usar.En general, se considera más legible, especialmente cuando une muchas tablas.
También se puede reemplazar fácilmente con un
OUTER JOIN
cuando surja una necesidad.La
WHERE
sintaxis está más orientada al modelo relacional.Un resultado de dos tablas
JOIN
ed es un producto cartesiano de las tablas a las que se aplica un filtro que selecciona solo aquellas filas con columnas de unión coincidentes.Es más fácil ver esto con la
WHERE
sintaxis.En cuanto a su ejemplo, en MySQL (y en SQL en general) estas dos consultas son sinónimos.
También tenga en cuenta que MySQL también tiene una
STRAIGHT_JOIN
cláusula.Con esta cláusula, puede controlar el
JOIN
orden: qué tabla se escanea en el bucle externo y cuál está en el bucle interno.No puede controlar esto en MySQL usando la
WHERE
sintaxis.fuente
Oracle
,SQL Server
,MySQL
yPostgreSQL
- sí. Para otros sistemas, probablemente también, pero es mejor que lo verifique.WHERE
cláusula también está en el estándar ANSI.@Bill Karwin
: laJOIN
palabra clave no fue parte de los estándares de propiedad hasta el pasado más reciente de lo que parece. Se abrió caminoOracle
solo en versión9
yPostgreSQL
en versión7.2
(ambos lanzados en2001
). La aparición de esta palabra clave fue parte deANSI
la adopción estándar, y es por eso que esta palabra clave generalmente está asociadaANSI
, a pesar de que esta última también admite coma como sinónimoCROSS JOIN
.WHERE
cláusula (sin condiciones, una unión es equivalente a una unión cruzada, como usted dijo). ANSI SQL-92 agregó laJOIN
palabra clave y la sintaxis relacionada, pero la sintaxis de estilo de coma todavía es compatible con la compatibilidad con versiones anteriores.Otros han señalado que
INNER JOIN
ayuda a la legibilidad humana, y esa es una prioridad, estoy de acuerdo.Permítanme intentar explicar por qué la sintaxis de combinación es más legible.
Una
SELECT
consulta básica es esta:La
SELECT
cláusula nos dice qué estamos recuperando; laFROM
cláusula nos dice dónde estamos recibiendo desde, y laWHERE
cláusula nos dice , que los que estamos recibiendo.JOIN
es una declaración sobre las tablas, cómo se unen (conceptualmente, en realidad, en una sola tabla).Cualquier elemento de consulta que controle las tablas, de donde obtenemos cosas, pertenece semánticamente a la
FROM
cláusula (y, por supuesto, ahí es dondeJOIN
van los elementos). Poner elementos de unión en laWHERE
cláusula combina el cuál y el de dónde , por esoJOIN
se prefiere la sintaxis.fuente
Aplicación de declaraciones condicionales en ON / WHERE
Aquí he explicado los pasos de procesamiento de consultas lógicas.
Referencia: Inside Microsoft® SQL Server ™ 2005 T-SQL Querying
Editor: Microsoft Press
Pub Fecha: 07 de marzo de 2006
Imprimir ISBN-10: 0-7356-2313-9
Imprimir ISBN-13: 978-0-7356-2313-2
Páginas: 640
Dentro de Microsoft® SQL Server ™ 2005 Consulta T-SQL
El primer aspecto notable de SQL que es diferente de otros lenguajes de programación es el orden en que se procesa el código. En la mayoría de los lenguajes de programación, el código se procesa en el orden en que está escrito. En SQL, la primera cláusula que se procesa es la cláusula FROM, mientras que la cláusula SELECT, que aparece primero, se procesa casi en último lugar.
Cada paso genera una tabla virtual que se utiliza como entrada para el siguiente paso. Estas tablas virtuales no están disponibles para la persona que llama (aplicación cliente o consulta externa). Solo la tabla generada por el paso final se devuelve a la persona que llama. Si una determinada cláusula no se especifica en una consulta, simplemente se omite el paso correspondiente.
Breve descripción de las fases de procesamiento de consultas lógicas
No se preocupe demasiado si la descripción de los pasos no parece tener mucho sentido por ahora. Estos se proporcionan como referencia. Las secciones que vienen después del ejemplo de escenario cubrirán los pasos con mucho más detalle.
FROM: se realiza un producto cartesiano (unión cruzada) entre las dos primeras tablas de la cláusula FROM y, como resultado, se genera la tabla virtual VT1.
ON: el filtro ON se aplica a VT1. Solo las filas para las cuales
<join_condition>
es VERDADERO se insertan en VT2.OUTER (join): si se especifica un OUTER JOIN (a diferencia de CROSS JOIN o INNER JOIN), las filas de la tabla o tablas preservadas para las que no se encontró una coincidencia se agregan a las filas de VT2 como filas externas, generando VT3. Si aparecen más de dos tablas en la cláusula FROM, los pasos 1 a 3 se aplican repetidamente entre el resultado de la última unión y la siguiente tabla en la cláusula FROM hasta que se procesen todas las tablas.
WHERE: el filtro WHERE se aplica a VT3. Solo las filas para las que
<where_condition>
es VERDADERO se insertan en VT4.GROUP BY: las filas de VT4 se organizan en grupos según la lista de columnas especificada en la cláusula GROUP BY. Se genera VT5.
CUBO | ROLLUP: los supergrupos (grupos de grupos) se agregan a las filas desde VT5, generando VT6.
HAVING: el filtro HAVING se aplica a VT6. Solo los grupos para los que
<having_condition>
es VERDADERO se insertan en VT7.SELECCIONAR: se procesa la lista SELECCIONAR, generando VT8.
DISTINCT: las filas duplicadas se eliminan de VT8. Se genera VT9.
ORDER BY: las filas de VT9 se ordenan según la lista de columnas especificada en la cláusula ORDER BY. Se genera un cursor (VC10).
ARRIBA: El número o porcentaje especificado de filas se selecciona desde el comienzo de VC10. La tabla VT11 se genera y se devuelve a la persona que llama.
Por lo tanto, (INNER JOIN) ON filtrará los datos (el recuento de datos de VT se reducirá aquí mismo) antes de aplicar la cláusula WHERE. Las siguientes condiciones de unión se ejecutarán con datos filtrados que mejoran el rendimiento. Después de eso, solo la condición WHERE aplicará condiciones de filtro.
(La aplicación de declaraciones condicionales en ON / WHERE no hará mucha diferencia en algunos casos. Esto depende de cuántas tablas haya unido y el número de filas disponibles en cada tabla de unión)
fuente
La sintaxis de unión ANSI implícita es más antigua, menos obvia y no recomendada.
Además, el álgebra relacional permite la intercambiabilidad de los predicados en la
WHERE
cláusula y elINNER JOIN
, por lo que incluso lasINNER JOIN
consultas conWHERE
cláusulas pueden hacer que el optimizador reorganice los predicados.Le recomiendo que escriba las consultas de la manera más fácil posible.
Algunas veces esto incluye hacer lo
INNER JOIN
relativamente "incompleto" y poner algunos de los criterios en elWHERE
simplemente para hacer que las listas de criterios de filtrado sean más fáciles de mantener.Por ejemplo, en lugar de:
Escribir:
Pero depende, por supuesto.
fuente
Las uniones implícitas (que es lo que se conoce como su primera consulta) se vuelven mucho más confusas, difíciles de leer y difíciles de mantener una vez que necesita comenzar a agregar más tablas a su consulta. Imagine hacer esa misma consulta y tipo de unión en cuatro o cinco tablas diferentes ... es una pesadilla.
Usar una unión explícita (su segundo ejemplo) es mucho más legible y fácil de mantener.
fuente
También señalaré que el uso de la sintaxis anterior está más sujeto a errores. Si utiliza uniones internas sin una cláusula ON, obtendrá un error de sintaxis. Si usa la sintaxis anterior y olvida una de las condiciones de unión en la cláusula where, obtendrá una unión cruzada. Los desarrolladores a menudo arreglan esto agregando la palabra clave distinta (en lugar de arreglar la unión porque todavía no se dan cuenta de que la unión en sí está rota), lo que puede parecer que soluciona el problema, pero ralentizará la consulta considerablemente.
Además, para el mantenimiento si tiene una unión cruzada en la sintaxis anterior, ¿cómo sabrá el mantenedor si quería tener una (hay situaciones en las que se necesitan uniones cruzadas) o si fue un accidente que debería solucionarse?
Permítame señalarle esta pregunta para ver por qué la sintaxis implícita es mala si usa combinaciones izquierdas. Sybase * = a Ansi Standard con 2 tablas externas diferentes para la misma tabla interna
Además (discurso personal aquí), el estándar que usa las uniones explícitas tiene más de 20 años, lo que significa que la sintaxis de unión implícita ha quedado desactualizada durante esos 20 años. ¿Escribiría el código de la aplicación utilizando una sintaxis que ha estado desactualizada durante 20 años? ¿Por qué quieres escribir el código de la base de datos que es?
fuente
HAVING
que ha estado 'desactualizado' desde que SQL comenzó a admitir tablas derivadas. También me doy cuenta de que no lo usasNATURAL JOIN
, aunque yo diría que estáINNER JOIN
"desactualizado". Sí, tiene sus razones (¡no es necesario que las repita aquí!): Mi punto es que aquellos a quienes les gusta usar la sintaxis anterior también tienen sus razones y la edad relativa de la sintaxis es de poca o ninguna relevancia.Tienen un significado diferente legible para los humanos.
Sin embargo, dependiendo del optimizador de consultas, pueden tener el mismo significado para la máquina.
Siempre debe codificar para que sea legible.
Es decir, si esta es una relación incorporada, use la unión explícita. si está haciendo coincidir datos débilmente relacionados, use la cláusula where.
fuente
El estándar SQL: 2003 cambió algunas reglas de precedencia, por lo que una declaración JOIN tiene prioridad sobre una unión "coma". En realidad, esto puede cambiar los resultados de su consulta dependiendo de cómo se configure. Esto causa algunos problemas para algunas personas cuando MySQL 5.0.12 cambió a adherirse al estándar.
Entonces, en su ejemplo, sus consultas funcionarían igual. Pero si agregó una tercera tabla: SELECT ... FROM table1, table2 JOIN table3 ON ... WHERE ...
Antes de MySQL 5.0.12, table1 y table2 se unirían primero, luego table3. Ahora (5.0.12 y en adelante), table2 y table3 se unen primero, luego table1. No siempre cambia los resultados, pero puede hacerlo y es posible que ni siquiera se dé cuenta.
Ya nunca uso la sintaxis "coma", optando por su segundo ejemplo. De todos modos, es mucho más legible, las condiciones de UNIÓN son con las UNIONES, no separadas en una sección de consulta separada.
fuente
Sé que estás hablando de MySQL, pero de todos modos: en Oracle 9, las uniones explícitas y las implícitas generarían diferentes planes de ejecución. AFAIK que se ha resuelto en Oracle 10+: ya no hay tanta diferencia.
fuente
La sintaxis de unión ANSI es definitivamente más portátil.
Estoy pasando por una actualización de Microsoft SQL Server, y también mencionaría que la sintaxis = * y * = para las uniones externas en SQL Server no es compatible (sin el modo de compatibilidad) para el servidor sql 2005 y posterior.
fuente
*=
y=*
nunca fueron ANSI y nunca fueron una buena notación. Por eso era necesario ON - para combinaciones externas en ausencia de subselects (que consiguió añadió al mismo tiempo, por lo que no son realmente necesarios en CRUZ Y uniones internas.)Si a menudo está programando procedimientos almacenados dinámicos, se enamorará de su segundo ejemplo (usando where). Si tiene varios parámetros de entrada y mucho desorden morfo, entonces esa es la única manera. De lo contrario, ambos ejecutarán el mismo plan de consulta, por lo que definitivamente no hay una diferencia obvia en las consultas clásicas.
fuente