2014-10-28 23 views
5

Cosa c'è di sbagliato in questo semplice join esterno SQL?In che modo A un join esterno sinistro B restituisce più righe di quelle in A?

select count(*) from A -- 25766 
select count(*) from B -- 1242 
select count(*) from A left outer join B on A.b = B.b -- 310176 

restituire rispettivamente 25766, 1242 e 310176 righe. (Questo è per Microsoft SQL Server 2012.) Come può A left outer join B restituire sempre più righe di quelle esistenti in A, in particolare con lo schema this Venn? Suppongo che sto facendo uno stupido errore ma che cos'è?

+2

Può essere che la colonna b non è l'intera chiave? – Jens

+0

+1 controllerò. Come potrebbe spiegare questo 310176? – Drux

+2

Se b è solo la parte della chiave, può essere quella una riga in un riferimento molte più righe in B e se nel record di esempio 1 di Un riferimento 12,0 ... righe in B ottieni il risultato. – Jens

risposta

14

Ciò può accadere quando la colonna b non è univoca nella tabella B. Supponiamo di avere questi dati:

 
    A  B 
+---+ +---+---+ 
| b | | b | c | 
+---+ +---+---+ 
| 1 | | 2 | 1 | 
| 2 | | 2 | 2 | 
+---+ +---+---+ 

Quando sei partito-join A-B sulla colonna di b, si ottiene

 
+-----+------+------+ 
| A.b | B.b | B.c | 
+-----+------+------+ 
| 1 | NULL | NULL | 
| 2 | 2 | 1 | 
| 2 | 2 | 2 | 
+-----+------+------+ 

che dà tre righe in totale, anche se entrambi A e B avere solo due file ciascuno.

+0

+1 Sì, 'select count (distinto b) da B' restituisce 197 e 197 << 1242. – Drux

3

Non c'è niente di strano (e questa situazione si applica anche ai join interni). Un join esterno sinistro:

  • restituisce tutte le righe da un incrocio B dove la condizione di join partita
  • e restituisce tutte le righe da A in cui la condizione di join non corrisponde

Così al minimo la query restituirà 25766 righe ma potrebbero essercene di più. E 'possibile avere una riga della tabella A che corrisponde molte righe nella tabella B. Esempio:

A    B    Result 
+----+----+ +-----+----+ +------+-----+-----+------+ 
| id| b| | id| b| | a.id| a.b| b.b| b.id| 
+----+----+ +-----+----+ +------+-----+-----+------+ 
| 1| 10| | 123| 10| |  1| 10| 10| 123| 
+----+----+ | 456| 10| |  1| 10| 10| 456| 
      +-----+----+ +------+-----+-----+------+ 

Questo restituisce due file, anche se c'è una riga nella tabella A.