2012-08-30 7 views
10

Ho avuto difficoltà a cercare su Google una risposta, ma .... qualcuno può spiegarmi la differenza tra mettere la condizione ON di un JOIN con lo JOIN stesso vs mettendo l'ON alla fine di tutti gli altri JOIN.In SQL, Qual è la differenza una condizione ON dopo un join vs alla fine di più join

Ecco un esempio http://sqlfiddle.com/#!3/e0a0f/3

CREATE TABLE TableA (Email VARCHAR(100), SomeNameA VARCHAR(100)) 
CREATE TABLE Tableb (Email VARCHAR(100), SomeNameB VARCHAR(100)) 
CREATE TABLE Tablec (Email VARCHAR(100), SomeNameC VARCHAR(100)) 

INSERT INTO TableA SELECT '[email protected]', 'JoeA' 
INSERT INTO TableA SELECT '[email protected]', 'JaneA' 
INSERT INTO TableA SELECT '[email protected]', 'DaveA' 
INSERT INTO TableB SELECT '[email protected]', 'JoeB' 
INSERT INTO TableB SELECT '[email protected]', 'DaveB' 
INSERT INTO TableC SELECT '[email protected]', 'JoeC' 
INSERT INTO TableC SELECT '[email protected]', 'DaveC' 


SELECT TOP 2 a.*, 
      b.*, 
      c.* 
FROM TableA a 
     LEFT OUTER JOIN TableB b 
        ON a.email = b.email 
     INNER JOIN TableC c 
        ON c.Email = b.email; 

SELECT TOP 2 a.*, 
      b.*, 
      c.* 
FROM TableA a 
     LEFT OUTER JOIN TableB b 
     INNER JOIN TableC c 
        ON c.Email = b.email 
        ON a.email = b.email; 

non capisco il motivo per cui queste due istruzioni SELECT producono risultati diversi.

risposta

12

Ciò che importa sono gli ordini di join. Tratta le tue espressioni come se ogni join producesse una tabella "virtuale" temporanea.

Quindi, quando si scrive

FROM TableA a 
LEFT OUTER JOIN TableB b ON a.email = b.email 
INNER JOIN TableC c ON c.Email = b.email ; 

allora ordine è il seguente:

  1. TableA è rimasto unito alla TableB produrre relazione temporanea V1
  2. V1 è unita interna a TableC.

Meanhwile quando si scrive:

FROM TableA a 
LEFT OUTER JOIN TableB b 
INNER JOIN TableC c ON c.Email = b.email ON a.email = b.email; 

per poi è il seguente:

  1. TableB è interiore unito a TableC produrre relazione temporanea V1.
  2. TableA viene lasciato unito a V1.

Così risultati sono diversi.Si consiglia in genere di utilizzare la parentesi in tali situazioni per migliorare la leggibilità della query:

FROM TableA a 
LEFT OUTER JOIN 
    (TableB b INNER JOIN TableC c ON c.Email = b.email) 
ON a.email = b.email; 
+0

applausi per questa spiegazione approfondita – MakkyNZ

4

Nel secondo esempio, la parte ON a.email = b.email appartiene alla LEFT JOIN.
se scritto come questo, significa quanto segue:

INNER JOIN TableC con TableB e LEFT OUTER JOIN il risultato con TableA.

Il risultato sarà tutte le righe da TableA è unito con le righe da TableB che hanno anche una voce in TableC.

Il primo esempio si intende il seguente:

LEFT OUTER JOIN TabellaB con TableA e INNER JOIN TableC del risultato. Questo è equivalente all'utilizzo di INNER JOIN per TableB.
Spiegazione: Quando si LEFT OUTER JOIN TabellaA con TabellaB si ottengono tutte le righe da TabellaA e per le righe corrispondenti in TabellaB si otterranno anche quei dati. Nel set di risultati avrai righe con b.email = NULL e questo sarà ora INNER JOIN con TableC. Finché non vi è alcuna voce in TableC con email = NULL otterrai i risultati che hai osservato.

Problemi correlati