2011-12-09 16 views
6

El 2 siguientes consultas me están dando resultados diferentes:¿Importa la ubicación de una condición?

SELECT A.source_code, B.quantity 
FROM Table_A AS A 
LEFT JOIN Table_B AS B ON B.merchant_id = A.merchant_id 
    AND B.agent_id = A.agent_id 
    AND B.default IS NULL 
WHERE A.month='2011-10-01' 
    AND B.type='600' 

Y

SELECT A.source_code, B.quantity 
FROM Table_A AS A 
LEFT JOIN Table_B AS B ON B.merchant_id = A.merchant_id 
    AND B.agent_id = A.agent_id 
WHERE A.month='2011-10-01' 
    AND B.type='600' 
    AND B.default IS NULL 

Yo había asumido que la condición hace la misma operación en ambas consultas, solamente en momentos diferentes. ¿Me estoy perdiendo de algo?

Respuesta

3

Son y deben ser diferentes.

Considere el caso en el que tiene una a con una b que coincide con los identificadores de comerciante y de agend, y b.default no es nulo.

En el primer caso, encontrará la a, y luego encontrará ninguna b que cumpla con los criterios, porque no hay ninguna que coincida con la ID Y el valor predeterminado es nulo. Pero debido a que es una combinación de la izquierda, usted todavía obtiene un registro con los datos "a" en la salida.

En el segundo caso, encontrará la a y encontrará una b correspondiente. Pero como b falla la cláusula WHERE, el registro se excluye de la salida.

Si está haciendo una unión completa, poner una condición en ON frente a WHERE no cambiará la salida. Pero en una combinación izquierda o derecha, SÍ cambia la salida en la forma en que traté de describir arriba.

1

El primero le mostrará solo los registros coincidentes de B que también tienen un valor de NULL para default.

La segunda variante le mostrará todos los registros desde B, ya que el filtro se está aplicando después de que se ejecute OUTER JOIN. Como los registros no coincidentes aparecen con los valores NULL, esto coincide con todos los registros.

Sin embargo, también se debe tener en cuenta que cuando filtra en la mesa JOIN ed en la cláusula WHERE que están obligando a una INNER JOIN, por lo que en realidad tienen dos problemas en el trabajo aquí.

0

No exactamente, pero en este caso sí.

La cláusula WHERE filtra el conjunto de resultados, mientras que la cláusula ON detiene la unión de las filas en primer lugar. El conjunto de resultados puede ser grande, lo que hace que trabaje mucho en el gran conjunto de resultados. Si se uniera a otras tablas, sería una gran diferencia, porque detener las filas que se unen antes puede cortar grandes cantidades de filas más adelante.

La mayoría de los analizadores modernos optimizarán la consulta de todos modos, por lo que el efecto de rendimiento debería ser el mismo.

Por último, debido a que los filtros cláusula WHERE, la izquierda se unen mantener al menos una fila con la condición en la cláusula ON, pero tirarlo por la condición de la cláusula WHERE.

+0

Esa es la cosa. Tengo otras combinaciones en mi consulta real, y hay una gran diferencia notable. Pero el primer caso arroja más casos que el segundo. Intuitivamente, como dijiste, ¿no debería ser al revés? – flipflop99

Cuestiones relacionadas