Solo tenga cuidado con la diferencia con las uniones externas. Una consulta donde se añade un filtro de b.IsApproved
(en la tabla de la derecha, Bar) a la ON
condición del JOIN
:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
Es NO lo mismo que colocar el filtro en el WHERE
cláusula:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1);
Dado que para 'fracasado' exterior se une a Bar
(es decir, donde no hay b.BarId
para un f.BarId
), esto dejará b.IsApproved
como NULL
para todos tales fa iled join rows, y estas filas serán filtradas.
Otra forma de ver esto es que para la primera consulta, LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId)
siempre devolverá las filas de la tabla IZQUIERDA, ya que LEFT OUTER JOIN
garantiza que las filas de la tabla IZQUIERDA se devolverán incluso si la unión falla. Sin embargo, el efecto de agregar (b.IsApproved = 1)
a la condición LEFT OUTER JOIN
es anular las columnas de la tabla derecha cuando (b.IsApproved = 1)
es falso, es decir, según las mismas reglas que se aplican normalmente a una condición LEFT JOIN
en (b.BarId = f.BarId)
.
actualización: Para completar la pregunta hecha por Conrad, la LOJ equivalente para un filtro opcional sería:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
es decir El WHERE
cláusula debe tener en cuenta tanto la condición de si la unión falla (NULL)
y el filtro se debe ignorar, y donde la unión tiene éxito y se debe aplicar el filtro.(b.IsApproved
o b.BarId
podrían ser probados para NULL
)
He puesto un SqlFiddle together here que demuestra las diferencias entre las diversas ubicaciones de la b.IsApproved
filtro con relación a la JOIN
.
Aquí hay una pregunta similar: http://stackoverflow.com/questions/2509987/which-sql-query-is-faster-filter-on-join-criteria-or-where-clause –
La máquina lo resolverá y optimizarlo adecuadamente Sin embargo, para los humanos que necesitarán depurar \ modificar \ apoyar su código en años a partir de ahora, mantenga las condiciones de filtrado en 'DONDE' y condiciones de unión en 'ENCENDIDO'. –
@KM. No siempre sé cómo diferenciar qué es una condición de unión y qué es un filtro. Por ejemplo [en esta respuesta] (http://stackoverflow.com/a/9303069/119477) Creo que es mejor en la unión, entonces ¿es una "condición de unión"? [Aquí hay otro ejemplo] (http://stackoverflow.com/a/6473403/119477) que ni siquiera sé cómo volver a escribir la cláusula where equivalente. –