2010-04-27 18 views
34

Las siguientes declaraciones dan el mismo resultado (uno está utilizando on, y el otro usando where):En SQL/MySQL, ¿cuál es la diferencia entre "ON" y "WHERE" en una instrucción join?

mysql> select * from gifts INNER JOIN sentGifts ON gifts.giftID = sentGifts.giftID; 
mysql> select * from gifts INNER JOIN sentGifts WHERE gifts.giftID = sentGifts.giftID; 

sólo puedo ver en el caso de una combinación externa izquierda búsqueda de los casos "sin precedentes":
(para descubrir los dones que nunca fueron enviadas por nadie)

mysql> select name from gifts LEFT OUTER JOIN sentgifts 
      ON gifts.giftID = sentgifts.giftID 
      WHERE sentgifts.giftID IS NULL; 

En este caso, primero se está utilizando on, y luego where. ¿El on primero hace la coincidencia, y luego where hace el filtrado "secundario"? ¿O hay una regla más general de usar on contra where? Gracias.

+0

Muy similar a http://stackoverflow.com/questions/2559194/difference-between-and-where-in- join –

+1

Esta pregunta tiene el mejor título de los dos. – ripper234

Respuesta

38

WHERE es una parte de la consulta SELECT como un todo, ON es una parte de cada unión.

ON solo puede hacer referencia a los campos de las tablas utilizadas anteriormente.

Cuando no existe una coincidencia real con un registro en la tabla de la izquierda, LEFT JOIN devuelve un registro de la tabla derecha con todos los campos establecidos en NULLS. La cláusula WHERE luego evalúa y filtra esto.

En su consulta, solo se devuelven los registros de gifts sin coincidencia en 'sendgifts'.

Aquí está el ejemplo

gifts 

1 Teddy bear 
2 Flowers 

sentgifts 

1 Alice 
1 Bob 

--- 
SELECT * 
FROM gifts g 
LEFT JOIN 
     sentgifts sg 
ON  g.giftID = sg.giftID 

--- 

1 Teddy bear 1  Alice 
1 Teddy bear 1  Bob 
2 Flowers  NULL NULL -- no match in sentgifts 

--- 
SELECT * 
FROM gifts g 
LEFT JOIN 
     sentgifts sg 
ON  g.giftID = sg.giftID 
WHERE sg.giftID IS NULL 

--- 

2 Flowers  NULL NULL -- no match in sentgifts 

Como se puede ver, no puede competir con real puede dejar un NULL en sentgifts.id, por lo que sólo los regalos que nunca no habían sido enviados son devueltos.

0

Si está utilizando un JOIN, debe especificar las condiciones a las que se está uniendo. Esa lista va en una cláusula ON. Una cláusula WHERE se usa para condicionar datos para cualquier parte de la consulta.

2

Aunque los resultados son los mismos, el 'ENCENDIDO' hace primero la unión y luego recupera los datos del conjunto unido. La recuperación es más rápida y la carga es menor. Pero al usar 'DONDE' se buscan primero los dos conjuntos de resultados y luego se aplica la condición. Entonces sabes lo que se prefiere.

11

Al usar INNER JOIN, ON y WHERE tendrá el mismo resultado. Así,

select * 
from Table1 t1 
inner join Table2 t2 on t1.id = t2.id 
where t1.Name = 'John' 

tendrá exactamente el mismo resultado que

select * 
from Table1 t1 
inner join Table2 t2 on t1.id = t2.id 
    and t1.Name = 'John' 

Como se ha señalado, este no es el caso cuando se utiliza OUTER JOIN. El plan de consulta que se genera depende de la plataforma de la base de datos y de los detalles de la consulta, y está sujeto a cambios, por lo que tomar decisiones sobre esa base por sí solo no proporcionará un plan de consulta garantizado.

Como regla general, debe usar las columnas que unen sus tablas en las cláusulas ON y las columnas que se usan para filtrar en las cláusulas WHERE. Esto proporciona la mejor legibilidad.

+0

¿Es correcto usar "ENCENDIDO" con algo más complejo que campo1 = campo2? – skan

+0

Sí, a menudo hay cláusulas ON de varias columnas. – RedFilter

+0

Quiero decir, ¿se pueden usar expresiones complejas más allá de la comparación de columnas? – skan

40

La cláusula ON define la relación entre las tablas.

La cláusula WHERE describe las filas que le interesa.

Muchas veces se puede intercambiarlos y aún obtener el mismo resultado, sin embargo, esto no siempre es el caso con una combinación externa izquierda.

  • Si la cláusula ON no sigue recibiendo una fila de columnas de la tabla izquierda pero con nulos en las columnas de la tabla derecha.
  • Si la cláusula WHERE falla, no obtendrá esa fila en absoluto.
+0

Votación a favor de las dos últimas declaraciones – Sekai

Cuestiones relacionadas