2010-04-01 23 views
13

¿Cuál es la diferencia entreDiferencia entre "y" y "donde" en une

SELECT DISTINCT field1 
    FROM table1 cd 
    JOIN table2 
    ON  cd.Company = table2.Name 
     and table2.Id IN (2728) 

y

SELECT DISTINCT field1 
    FROM table1 cd 
    JOIN table2 
    ON cd.Company = table2.Name 
where table2.Id IN (2728) 

ambos devuelven el mismo resultado y ambos tienen la misma explicar la salida

+1

Consejo pequeño: Eche un vistazo al plan de ejecución, que podría darle más información. SQL hace muchas optimizaciones de consultas. – Zyphrax

Respuesta

24

En primer lugar, existe una diferencia semántica. Cuando tienes una unión, estás diciendo que la relación entre las dos tablas está definida por esa condición. Entonces, en su primer ejemplo, usted está diciendo que las tablas están relacionadas por cd.Company = table2.Name AND table2.Id IN (2728). Cuando utiliza la cláusula WHERE, está diciendo que la relación está definida por cd.Company = table2.Name y que solo desea las filas donde se aplica la condición table2.Id IN (2728). Aunque dan la misma respuesta, significa cosas muy diferentes para un programador que lee su código.

En este caso, la cláusula WHERE es casi seguramente lo que quiere decir, así que debe usarla.

En segundo lugar, en realidad hay una diferencia en el resultado en el caso de que use un LEFT JOIN en lugar de un INNER JOIN. Si incluye la segunda condición como parte de la unión, igualmente obtendrá una fila de resultados si la condición falla; obtendrá valores de la tabla izquierda y nulos para la tabla correcta. Si incluye la condición como parte de la cláusula WHERE y esa condición falla, no obtendrá la fila en absoluto.

Aquí hay un ejemplo para demostrar esto.

de consulta 1 (WHERE):

SELECT DISTINCT field1 
    FROM table1 cd 
    LEFT JOIN table2 
    ON cd.Company = table2.Name 
WHERE table2.Id IN (2728); 

Resultado:

field1 
200 

Consulta 2 (AND):

SELECT DISTINCT field1 
    FROM table1 cd 
    LEFT JOIN table2 
    ON cd.Company = table2.Name 
    AND table2.Id IN (2728); 

Resultado:

field1 
100 
200 

Los datos de prueba utilizados:

CREATE TABLE table1 (Company NVARCHAR(100) NOT NULL, Field1 INT NOT NULL); 
INSERT INTO table1 (Company, Field1) VALUES 
('FooSoft', 100), 
('BarSoft', 200); 

CREATE TABLE table2 (Id INT NOT NULL, Name NVARCHAR(100) NOT NULL); 
INSERT INTO table2 (Id, Name) VALUES 
(2727, 'FooSoft'), 
(2728, 'BarSoft'); 
+1

+1 para el escenario 'LEFT JOIN' – cjk

+0

+1 por mencionar LEFT JOINs. aún así, indudablemente señalaré mi respuesta http://stackoverflow.com/questions/2559194/difference-between-and-where-in-joins/2559769#2559769 para tal vez incluso más detalles y razones :) – Unreason

+0

En su ejemplo (consulta 2 con AND) si tuviéramos table1.Id IN (100); aún así devolvería dos filas ... ¿por qué es esto? ... – psj01

1

Hay no hay diferencia "ON" es como un sinónimo de "dónde", por lo que E l segundo tipo de lee como:

JOIN table2 WHERE cd.Company = table2.Name AND table2.Id IN (2728)

+0

Según http://dev.mysql.com/doc/refman/4.1/en/join.html, no parece que ON sea un sinónimo de WHERE. –

+2

Dije que es "como" un sinónimo. –

+0

y solo para joins.inner joins. – nawfal

3
  • La unión se utiliza para reflejar las relaciones de entidad
  • la cláusula where se filtra resultados .

Así las cláusulas de unión son 'estático' (a menos que cambien las relaciones de entidad), mientras que las cláusulas
donde son casos de uso específico.

0

No hay diferencia cuando el motor de optimización de consultas lo desglosa para sus operadores de consulta relevantes.

5

SQL proviene de relational algebra.

Una forma de ver la diferencia es que las UNIONES son operaciones en conjuntos que pueden producir más registros o menos registros en el resultado de los que tenía en las tablas originales. Por otro lado DONDE siempre restringirá la cantidad de resultados.

El resto del texto es una explicación adicional.


Para obtener una descripción general de los tipos de unión, consulte article nuevamente.

Cuando dije que la condición where siempre restringirá los resultados, debe tener en cuenta que cuando estamos hablando de consultas en dos (o más) tablas, de alguna manera debe emparejar registros de estas tablas, incluso si hay sin palabra clave JOIN.

Por lo tanto, en SQL, si las tablas están simplemente separadas por una coma, en realidad está utilizando una CROSS JOIN (producto cartesiano) que devuelve cada fila de una tabla para cada fila en la otra.

Y como este es un número máximo de combinaciones de filas de dos tablas, los resultados de cualquier DONDE en tablas unidas se pueden expresar como una operación JOIN.

Pero espere, hay excepciones a este máximo cuando introduce uniones IZQUIERDA, DERECHA y OPRIMA COMPLETA.

LEFT JOIN unirá registros de la tabla izquierda en un criterio dado con registros de la tabla correcta, PERO si los criterios de unión, mirando una fila de la tabla izquierda no se cumple para ningún registro en la tabla derecha IZQUIERDA JOIN aún devolverá un registro de la tabla de la izquierda y en las columnas que vendrían de la tabla correcta devolverá valores NULL (DERECHA JOIN funciona de manera similar pero desde el otro lado, FULL OUTER funciona como ambos al mismo tiempo).

Dado que la combinación cruzada predeterminada NO devuelve esos registros, no puede expresar estos criterios de unión con la condición WHERE y se ve obligado a utilizar la sintaxis JOIN (Oracle fue una excepción a esto con una extensión al estándar SQL y operador =, pero esto no fue aceptado por otros proveedores ni por el estándar).

Además, las uniones generalmente, pero no siempre, coinciden con la integridad referencial existente y sugieren relaciones entre entidades, pero no pondría tanto peso en eso ya que las condiciones pueden hacer lo mismo (excepto en el caso mencionado anteriormente) y para un buen RDBMS no hará una diferencia donde especifiques tus criterios.

+0

explicación muy limpia – user187291