Cláusula INNER JOIN ON vs WHERE
Para simplificar, supongamos 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 en MySQL
?
INNER JOIN
es la sintaxis ANSI que debes usar.
Generalmente se considera más legible, especialmente cuando unes muchas tablas.
También se puede reemplazar fácilmente por un OUTER JOIN
cuando surja la necesidad.
La WHERE
sintaxis está más orientada al modelo relacional.
El 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 cuyas columnas unidas coinciden.
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ónimas.
Además, 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 puedes controlar esto en MySQL usando WHERE
la sintaxis.
Otros han señalado que eso INNER JOIN
ayuda a la legibilidad humana y estoy de acuerdo en que es una prioridad máxima.
Permítanme intentar explicar por qué la sintaxis de unión es más legible.
Una consulta básica SELECT
es esta:
SELECT stuff
FROM tables
WHERE conditions
La SELECT
cláusula nos dice lo que recibiremos a cambio; la FROM
cláusula nos dice de dónde lo obtenemos y la WHERE
cláusula nos dice cuáles obtenemos.
JOIN
es una declaración sobre las tablas, cómo están unidas (conceptualmente, en realidad, en una sola tabla).
Cualquier elemento de consulta que controle las tablas, de donde obtenemos el material, pertenece semánticamente a la FROM
cláusula (y, por supuesto, ahí es donde JOIN
van los elementos). Poner elementos de unión en la WHERE
cláusula combina el cuál y el dónde , es por eso que JOIN
se prefiere la sintaxis.
Aplicar declaraciones condicionales en ON / WHERE
Aquí he explicado los pasos lógicos del procesamiento de consultas.
Referencia: Inside Microsoft® SQL Server™ 2005 T-SQL Querying
Editor: Microsoft Press
Fecha de publicación: 7 de marzo de 2006
ISBN-10 de impresión: 0-7356-2313-9
ISBN-13 de impresión: 978-0-7356-2313-2
Páginas: 640
Dentro de las consultas T-SQL de Microsoft® SQL Server™ 2005
(8) SELECT (9) DISTINCT (11) TOP <top_specification> <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH {CUBE | ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <order_by_list>
El primer aspecto notable de SQL que lo diferencia de otros lenguajes de programación es el orden en el 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 se devuelve a la persona que llama la tabla generada por el paso final. Si una determinada cláusula no se especifica en una consulta, simplemente se omite el paso correspondiente.
Breve descripción de las fases del procesamiento de consultas lógicas
No te preocupes 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 del 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 que
<join_condition>
es VERDADERO se insertan en VT2.EXTERIOR (unión): si se especifica una UNIÓN EXTERNA (a diferencia de una UNIÓN CRUZADA o una UNIÓN INTERIOR), las filas de la tabla o tablas conservadas 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 combinación y la siguiente tabla en la cláusula FROM hasta que se procesen todas las tablas.
DÓNDE: El filtro DÓNDE 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 de VT5, generando VT6.
HAVING: El filtro HAVING se aplica a VT6. Sólo los grupos para los cuales
<having_condition>
es VERDADERO se insertan en VT7.SELECT: La lista SELECT se procesa generando VT8.
DISTINTO: 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 de filas especificado se selecciona desde el principio de VC10. La tabla VT11 se genera y se devuelve al autor de la llamada.
Por lo tanto, (INNER JOIN) ON filtrará los datos (el recuento de datos de VT se reducirá aquí) antes de aplicar la cláusula WHERE. Las condiciones de unión posteriores se ejecutarán con datos filtrados, lo que mejora el rendimiento. Después de eso, solo la condición WHERE aplicará las 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 se haya unido y del número de filas disponibles en cada tabla combinada)
La sintaxis ANSI de unión implícita es antigua, menos obvia y no se recomienda.
Además, el álgebra relacional permite la intercambiabilidad de los predicados en la WHERE
cláusula y el INNER JOIN
, por lo que incluso INNER JOIN
las consultas con WHERE
cláusulas pueden tener los predicados reorganizados por el optimizador.
Te recomiendo que escribas las consultas de la forma más legible posible.
A veces, esto incluye hacer que las listas de INNER JOIN
criterios de filtrado sean relativamente "incompletas" y poner algunos de los criterios simplemente WHERE
para que las listas de criterios de filtrado sean más fáciles de mantener.
Por ejemplo, en lugar de:
SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
ON ca.CustomerID = c.CustomerID
AND c.State = 'NY'
INNER JOIN Accounts a
ON ca.AccountID = a.AccountID
AND a.Status = 1
Escribir:
SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
AND a.Status = 1
Pero depende, claro.