2012-03-08 18 views
125

Sin tener en cuenta el rendimiento, ¿obtendré el mismo resultado de las consultas A y B a continuación? ¿Qué hay de C y D?¿La orden de unión importa en SQL?

-- A 
select * 
from a left join b 
      on <blahblah> 
     left join c 
      on <blahblan> 


-- B 
select * 
from a left join c 
      on <blahblah> 
     left join b 
      on <blahblan> 

-- C 
select * 
from a join b 
      on <blahblah> 
     join c 
      on <blahblan> 


-- D 
select * 
from a join c 
      on <blahblah> 
     join b 
      on <blahblan> 
+5

¿Qué es ''? ¿Estás uniendo A a B y A a C, o estás uniendo A a B y B a C? – beny23

+1

Hola Beny, el código en mi pregunta es una abstracción. No me importa unirme a A to B o A to C, solo quiero saber si la sintaxis de ese tipo proporcionará resultados idénticos. –

Respuesta

156

Para INNER une, no, el orden no es importante. Las consultas devolverán los mismos resultados, siempre y cuando cambie sus selecciones de SELECT * a SELECT a.*, b.*, c.*.


Para (LEFT, RIGHT o FULL) OUTER une, sí, las cuestiones de orden - y (actualizados) las cosas son mucho más complicadas.

En primer lugar, combinaciones externas no son conmutativas, así a LEFT JOIN b no es lo mismo que b LEFT JOIN a

combinaciones externas no son asociativos o bien, por lo que en sus ejemplos que involucran tanto (conmutatividad y asociatividad) Propiedades:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id 
    LEFT JOIN c 
    ON c.ac_id = a.ac_id 

es equivalente a:

a LEFT JOIN c 
    ON c.ac_id = a.ac_id 
    LEFT JOIN b 
    ON b.ab_id = a.ab_id 

pero:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id 
    LEFT JOIN c 
    ON c.ac_id = a.ac_id 
    AND c.bc_id = b.bc_id 

no es equivalente a:

a LEFT JOIN c 
    ON c.ac_id = a.ac_id 
    LEFT JOIN b 
    ON b.ab_id = a.ab_id 
    AND b.bc_id = c.bc_id 

Otro (esperemos más simple) ejemplo asociatividad. Piense en esto como (a LEFT JOIN b) LEFT JOIN c:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id   -- AB condition 
LEFT JOIN c 
    ON c.bc_id = b.bc_id   -- BC condition 

Este es equivalente aa LEFT JOIN (b LEFT JOIN c):

a LEFT JOIN 
    b LEFT JOIN c 
     ON c.bc_id = b.bc_id   -- BC condition 
    ON b.ab_id = a.ab_id   -- AB condition 

sólo porque tenemos "buenos" ON condiciones. Ambos ON b.ab_id = a.ab_id y c.bc_id = b.bc_id son controles de igualdad y no implican comparaciones NULL.

Usted puede incluso tener condiciones con otros operadores o los más complejos como: ON a.x <= b.x o ON a.x = 7 o ON a.x LIKE b.x o ON (a.x, a.y) = (b.x, b.y) y las dos consultas seguirían siendo equivalente.

Sin embargo, si cualquiera de estos implicados IS NULL o una función que se relaciona con los valores nulos como COALESCE(), por ejemplo, si la condición era b.ab_id IS NULL, a continuación, las dos consultas no serían equivalentes.

+2

Es más correcto decir que la combinación externa es asociativa siempre que ninguno de los predicados pueda ser satisfecho por una fila en la que todas las columnas de una tabla sean NULL, que decir que es asociativo siempre que los predicados no impliquen IS NULL o 'una función que está relacionada con nulos'. Uno puede imaginarse fácilmente un predicado que satisfaga la descripción anterior pero no la última, como 'a.somecol> 0 OR b.someothercol> 0'; la asociatividad podría fallar para esa condición. –

+0

Pero sí, creo que es técnicamente cierto decir que OUTER JOIN es asociativo siempre que el predicado no satisfaga ninguna de las condiciones que describo aquí: http://stackoverflow.com/questions/20022196/are-left- outer-joins-associative/20022925 # 20022925 (el primero de los cuales también rompe la asociatividad para INNER JOINs, pero es un enfoque tan barato y obvio para romperlo que tal vez no vale la pena mencionarlo) También vale la pena señalar que la mayoría tipo común de JOIN - unirse a una clave externa - no cumple ninguna de esas condiciones y por lo tanto es agradable y asociativo. –

+0

@MarkAmery Gracias, estaba teniendo dificultades para estructurar mis oraciones sobre ese punto (y ya he votado anteriormente esa respuesta;) –

4

para uniones regulares, no es así. TableA join TableB producirá el mismo plan de ejecución que TableB join TableA (para que sus ejemplos C y D sean los mismos)

para las uniones izquierda y derecha sí lo hace.TableA left Join TableB es diferente de TableB left Join TableA, PERO es el mismo que TableB right Join TableA

+2

Esto solo trata la conmutatividad, pero los ejemplos en la pregunta muestran que el solicitante está interesado en la asociatividad. La respuesta de ypercube se dirige a ambos. –

Cuestiones relacionadas