2012-09-13 18 views
18

instrucción SQL.Diferencia entre "on .. and" y "on .. where" en SQL Left Join?

1.select a.* from A a left join B b on a.id =b.id and a.id=2; 

2.select a.* from A a left join B b on a.id =b.id where a.id=2; 

¿Cuál es la diferencia de esta declaración de dos sql?

+1

http://stackoverflow.com/questions/10297231/where-clause-vs-on-when-using-join – Habib

+4

No es un duplicado, tener 'LEFT JOIN' aquí cambia significativamente la pregunta. – hvd

+1

@hvd - las preguntas pueden no ser exactas, pero dado que la mayoría de las respuestas están en la línea de "no importa para 'INNER JOIN', pero esto es lo que sería diferente para 'OUTER JOIN's ... " –

Respuesta

23
create table A(id int); 
create table B(id int); 

INSERT INTO A VALUES(1); 
INSERT INTO A VALUES(2); 
INSERT INTO A VALUES(3); 

INSERT INTO B VALUES(1); 
INSERT INTO B VALUES(2); 
INSERT INTO B VALUES(3); 

SELECT * FROM A; 
SELECT * FROM B; 

id 
----------- 
1 
2 
3 

id 
----------- 
1 
2 
3 

filtro en la unión para evitar que filas de ser añadido durante el proceso de combinación.

select a.*,b.* 
from A a left join B b 
on  a.id =b.id and a.id=2; 

id   id 
----------- ----------- 
1   NULL 
2   2 
3   NULL 

WHERE se filtrará después de que se haya producido la UNIÓN.

select a.*,b.* 
from A a left join B b 
on  a.id =b.id 
where a.id=2; 

id   id 
----------- ----------- 
2   2 
+0

Gracias por su detalle, explique –

+0

@ jack.li contenta para ayudarte :) –

+0

Por alguna razón no funcionó como se esperaba en este sqlfiddle: http://sqlfiddle.com/#!2/9684d/4 Pero cuando lo probé en MySQL funcionó exactamente como dijiste. –

8

seleccionar a. * De A a izquierda unir B b en a.id = b.id y a.id = 2;

Esto sólo se utiliza a.id en la condición de unión, por lo que los registros en los a.id <> 2 no consigue filtrados. Es posible obtener un resultado como este:

 
+------+------+ 
| a.id | b.id | 
+------+------+ 
| 1 | NULL | 
| 2 | 2 | 
| 3 | NULL | 
+------+------+ 

usted no selecciona ninguna de las columnas b 's, pero si lo hace, será más fácil de entender.

seleccione un. * De A a izquierda unir B b en a.id = b.id donde a.id = 2;

Ahora registros donde a.id <> 2 se filtran.

 
+------+------+ 
| a.id | b.id | 
+------+------+ 
| 2 | 2 | 
+------+------+ 
0

Como @hvd dice, el "dónde" cláusula de filtros de filas devueltas por la unión, por lo que el "donde" la versión no volverá filas exteriores-unido (que tienen a.id = null).

Sin embargo, hay otra diferencia significativa: incluso si las filas externas unidas no se filtraron, puede haber un aumento de rendimiento masivo al poner la condición en la cláusula "activada", porque el conjunto de resultados se hace más pequeño anteriormente.

Esto es particularmente pronunciado cuando una serie de otras tablas unidas por la izquierda sigue la que tiene la condición "y": puede evitar que las uniones ocurran en las siguientes tablas para filas inadecuadas y potencialmente cortar millones de filas para alcanzar el etapa de filtrado ("dónde").

0

Intento algún tiempo, y sé cuál es el motivo, solo se relaciona con una prioridad.

select * from A a left join B b on a.id=b.id and b.id=2 

esto significa una izquierda unirse (donde b.id = 2) esta es la condición filtro primero B

Select * from A a left join B b on a.id=b.id where a.id=2 

este medio después de unirse a B, después se filtra por a.id = 2

0

Si piensa en la sintaxis de una consulta SQL, la 'Y' amplía el bloque de unión (como si estuviera entre paréntesis) donde 'DONDE' define el inicio del bloque WHERE/filtro de la consulta.