Cláusula INNER JOIN ON vs WHERE

Resuelto JCCyC asked hace 15 años • 12 respuestas

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?

JCCyC avatar Jun 19 '09 23:06 JCCyC
Aceptado

INNER JOINes 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 JOINcuando surja la necesidad.

La WHEREsintaxis está más orientada al modelo relacional.

El resultado de dos tablas JOINed 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 WHEREsintaxis.

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_JOINcláusula.

Con esta cláusula, puede controlar el JOINorden: qué tabla se escanea en el bucle externo y cuál está en el bucle interno.

No puedes controlar esto en MySQL usando WHEREla sintaxis.

Quassnoi avatar Jun 19 '2009 16:06 Quassnoi

Otros han señalado que eso INNER JOINayuda 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 SELECTes esta:

SELECT stuff
FROM tables
WHERE conditions

La SELECTcláusula nos dice lo que recibiremos a cambio; la FROMcláusula nos dice de dónde lo obtenemos y la WHEREcláusula nos dice cuáles obtenemos.

JOINes 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 FROMcláusula (y, por supuesto, ahí es donde JOINvan los elementos). Poner elementos de unión en la WHEREcláusula combina el cuál y el dónde , es por eso que JOINse prefiere la sintaxis.

Carl Manaster avatar Jun 19 '2009 16:06 Carl Manaster

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.

  1. 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.

  2. ON: El filtro ON se aplica a VT1. Solo las filas para las que <join_condition>es VERDADERO se insertan en VT2.

  3. 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.

  4. DÓNDE: El filtro DÓNDE se aplica a VT3. Solo las filas para las que <where_condition>es VERDADERO se insertan en VT4.

  5. 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.

  6. CUBO | ROLLUP: Los supergrupos (grupos de grupos) se agregan a las filas de VT5, generando VT6.

  7. HAVING: El filtro HAVING se aplica a VT6. Sólo los grupos para los cuales <having_condition>es VERDADERO se insertan en VT7.

  8. SELECT: La lista SELECT se procesa generando VT8.

  9. DISTINTO: Las filas duplicadas se eliminan de VT8. Se genera VT9.

  10. 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).

  11. 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)

rafidheen avatar Dec 22 '2009 06:12 rafidheen

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 WHEREcláusula y el INNER JOIN, por lo que incluso INNER JOINlas consultas con WHEREclá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 JOINcriterios de filtrado sean relativamente "incompletas" y poner algunos de los criterios simplemente WHEREpara 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.

Cade Roux avatar Jun 19 '2009 16:06 Cade Roux