2009-03-10 14 views
9

Ho la seguente richiesta:Devo usare la parola chiave SQL JOIN per i join complessi su più tabelle?

select * 
    from tbA A, tbB B, tbC C, tbD D 
where 
    A.ID=B.ID and B.ID2= C.ID2 and A.ID=D.ID and C.ID3=D.ID3 and B.ID4=D.ID4 
and 
    A.Foo='Foo' 

Ho sentito più volte che questa sintassi unirsi sono ammortizzati, e che avrei dovuto utilizzare il 'ENTRA' parola chiave, invece.

Come si fa in un join così complicato (più tabelle unite su più colonne appartenenti a tabelle diverse)? Pensi che questa best practice valga ancora qui?

+0

La cosa bella utilizzando il formato ANSI è che la logica join è separato dalla tua logica di filtraggio. Rende molto chiaro vedere come le tabelle sono correlate a colpo d'occhio. – Barry

+0

Sì, è deprecato.E sì, dovresti pulire il tuo sql. – NotMe

+0

@Chris: beh, sembra che l'uso di questa sintassi non sia deprecato, mentre l'uso di * (per fare left joins) è (è dettagliato in un'altra risposta). re l'SQL, l'ho appena scritto come esempio – Brann

risposta

10

È una questione di gusti, ma la parola chiave JOIN mi piace di più. Rende la logica più chiara ed è più coerente con la sintassi LEFT OUTER JOIN che ne consegue. Nota che puoi anche usare INNER JOIN che è sinonimo di JOIN.

La sintassi è

a JOIN b 
    ON expression relating b to all of the tables before 

b può essere un join stessa. Per interiore si unisce non importa, ma per esterno è possibile controllare l'ordine dei join come questo:

select * from 
    a left join 
     d join c 
     on d.i = c.i 
    on a.k = d.k 

Ecco una che resta incollati al inner join tra D e c.

Ecco la vostra richiesta:

select * 
    from tbA A 
    join tbB B on A.ID = B.ID 
    join tbC C on B.ID2 = C.ID2 
    join tbD D on A.ID = D.ID and C.ID3 = D.ID3 and B.ID4 = D.ID4 
where 
    A.Foo='Foo' 
5

trovo unirsi sintassi molto più facile da capire

select * 
from tbA A 
inner join tbB B on a.id = b.id 
inner join tbC C on b.id2 = c.id2 
inner join tbD D on a.id = d.id and c.id3 = d.id3 and b.id4 = d.id4 
where A.Foo='Foo' 

Ora si può vedere chiaramente come i dati vengono uniti e che non è un molto complicato unire tutto.

BTW, il design del database nel tuo esempio ha un forte odore di mancanza di normalizzazione. Di solito dovresti avere una tabella che unisce a molti (un join b su a.bid = b.bid join c su a.cid = c.cid) o una catena (un join b su a.bid = b.bid join c su b.cid = c.cid).

MODIFICA. Aggiunta la parola chiave INTERNA opzionale che non modifica il risultato, ma lo rende più chiaro.

+0

hai ripetuto "a.id = b.id" due volte di proposito? – Brann

+0

Questo dovrebbe essere a.id = d.id3. –

+0

in realtà dovrebbe essere a.id = d.id :) Post corretto. Btw, questo semplice problema con la denominazione mostra chiaramente perché il design non è corretto. – user76035

2
SELECT * 
FROM tba AS a 
    JOIN tbb AS b ON a.id = b.id 
    JOIN tbc AS c ON b.id2 = c.id2 
    JOIN tbd AS d ON a.id = d.id AND c.id3 = d.id3 AND b.id4 = d.id4 
WHERE 
    a.foo = 'Foo' 

Anche se ho difficoltà a immaginare qualsiasi necessità. Bare di dare un esempio o eh nomi di tabelle più descrittivi?

2

JOIN sintassi è più leggibile (anche se io personalmente preferisco WHERE sintassi nei casi più semplici), e che è più importante, in grado di gestire e INNEROUTER si unisce in modo più chiaro.

WHERE non è deprecato e probabilmente non lo sarà mai.

È deprecato solo nel senso che diverse soluzioni alternative OUTER JOIN (come (*) e (+)) sono deprecate.

Non c'è niente che non si possa fare con JOIN che si può fare con WHERE, ma non viceversa.

+0

Infatti. Ora ricordo di aver visto questo messaggio quando si utilizza * in un join – Brann