2012-03-08 12 views
125

Ignorando le prestazioni, otterrò lo stesso risultato dalla query A e B qui sotto? Che ne dici di C e D?L'ordine di join è importante in 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

Cosa c'è di '' ? stai unendo A a B e A a C, o stai unendo A a B e B a C? – beny23

+1

Ciao Beny, il codice nella mia domanda è un'astrazione. Non sono preoccupato di unire A a B o A a C, voglio solo sapere che la sintassi del genere fornirà risultati identici. –

risposta

156

Per INNER unisce, no, l'ordine non importa. Le query restituiranno gli stessi risultati, a condizione che venga modificata la selezione da SELECT * a SELECT a.*, b.*, c.*.


Per (LEFT, RIGHT o FULL) OUTER unisce, sì, le questioni di ordine - e (aggiornati) le cose sono molto più complicate.

In primo luogo, outer join non sono commutativa, quindi a LEFT JOIN b non è lo stesso di b LEFT JOIN a

outer join non sono associativa o, in modo nei tuoi esempi che coinvolgono sia (proprietà commutativa e l'associatività) Proprietà:

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

è equivalente a:

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

ma:

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 

non equivale 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 

Un altro (si spera più semplice) esempio associatività. Pensate a questo come (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 

Questo equivale 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 

solo perché abbiamo "nice" ON condizioni. Entrambi ON b.ab_id = a.ab_id e c.bc_id = b.bc_id sono controlli di uguaglianza e non comportano confronti NULL.

Si può anche avere condizioni con altri operatori o quelli più complessi come: 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) e le due interrogazioni sarebbero ancora equivalente.

Se, tuttavia, nessuno di questi coinvolti IS NULL o una funzione che è legato a valori nulli come COALESCE(), per esempio se la condizione era b.ab_id IS NULL, allora le due domande non sarebbero equivalenti.

+2

È più corretto dire che il join esterno è associativo fintantoché non predicato può essere soddisfatta da una riga in cui tutte le colonne di una tabella sono NULL, che a dire che è associativo finché i predicati non comportano IS NULL o "una funzione correlata a null". Si può facilmente immaginare un predicato che soddisfi la precedente descrizione ma non la seconda, come 'a.somecol> 0 OR b.someothercol> 0'; l'associatività potrebbe fallire per quella condizione. –

+0

Ma sì, penso che è tecnicamente vero che outer join è associativa a patto che il predicato non soddisfa una delle condizioni che descrivo qui: http://stackoverflow.com/questions/20022196/are-left- esterno-join-associativa/20022925 # 20022925 (il primo dei quali si rompe anche l'associatività per INNER jOIN, ma è un approccio così a buon mercato e ovvio per romperla che forse non vale la pena menzionare.) e 'anche la pena sottolineare che il più Il tipo comune di JOIN - JOINing su una chiave estera - non soddisfa nessuna di queste condizioni e quindi è piacevole e associativa. –

+0

@MarkAmery Grazie, ho avuto un momento difficile strutturare le mie frasi su questo punto (e ho già upvoted che la risposta del tuo;) –

4

per join regolari, non è così. TableA join TableB produrrà lo stesso piano di esecuzione di TableB join TableA (quindi gli esempi C e D sarebbero gli stessi)

per join sinistro e destro.TableA left Join TableB è diverso TableB left Join TableA, ma la sua lo stesso rispetto TableB right Join TableA

+2

Questo solo indirizza la commutatività, ma gli esempi nella domanda mostrano che il richiedente è interessato all'associatività. La risposta di ypercube affronta entrambi. –