Qual è la differenza tra un INNER JOIN e un OUTER JOIN?


35

Sono nuovo di SQL e volevo sapere qual è la differenza tra questi due JOINtipi?

SELECT * 
FROM user u
INNER JOIN telephone t ON t.user_id = u.id

SELECT * 
FROM user u
LEFT OUTER JOIN telephone t ON t.user_id = u.id

Quando dovrei usare l'uno o l'altro?


6
si adatta come una domanda DBA? Questa mi sembra più una domanda di programmazione.
BlackICE,

1
@Davide i tuoi pensieri su Meta
Sathyajith Bhat il

@David quindi VtC se pensi che sia sbagliato per il sito. Possiamo sempre riaprire.
jcolebrand

3
Penso che questa sia un'ottima domanda e molto appropriata per il sito.
datagod

questo deve essere spostato da DBA a meno che un DBA noob adattato per ottimizzare le prestazioni del DB: P
AmDB

Risposte:


32
  • Un join interno selezionerà solo i record in cui le chiavi unite si trovano in entrambe le tabelle specificate.
  • Un join esterno sinistro selezionerà tutti i record dalla prima tabella e tutti i record nella seconda tabella corrispondenti alle chiavi unite.
  • Un join esterno destro selezionerà tutti i record dalla seconda tabella e tutti i record nella prima tabella che corrispondono alle chiavi unite.

Nel tuo primo esempio, restituirai un elenco di utenti e numeri di telefono solo se esiste almeno un record telefonico per l'utente.

Nel tuo secondo esempio, restituirai un elenco di tutti gli utenti, oltre a tutti i record telefonici se sono disponibili (se non sono disponibili, otterrai NULLi valori del telefono).


13

Ogni volta che qualcuno fa questa domanda, c'è la risposta: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

Spero ti possa aiutare a capire,


3
Ho lavorato con i join per 20 anni e quei diagrammi mi sembravano confusi.
Hogan,

3
Sono con @Hogan - i diagrammi di ven non sono la migliore spiegazione per questo .. una griglia che mostra quali combinazioni sarebbero restituite sarebbe probabilmente migliore.
Joe,

Tutto ciò che mostra è che non capisci un diagramma di Venn. Si collegano perfettamente ai tipi di join, ma tengono presente che sono uno strumento per aiutare a capire chi è nuovo per i join. Se hai già imparato a unirti con un concetto diverso in mente, allora è destinato a sembrare sconosciuto. Questo non è un problema, ma non è anche un buon indicatore dell'utilità dei diagrammi.
JamesRyan,

@jamesryan non è vero, non si relazionano perfettamente, i join sono simili al prodotto cartesiano degli insiemi, non all'intersezione e all'unione, l'analogo del diagramma di Venn funziona solo se si uniscono su chiavi univoche, se si dispone di chiavi duplicate, si perde l'aspetto cartesiano del prodotto.
Sarà

1
Non sono assolutamente d'accordo, i diagrammi di Venn hanno già un'interpretazione molto ben definita, impostano l'intersezione e l'unione. I join non si adattano a questa interpretazione quando si esegue il join su chiavi non univoche. Penso che tu interpreti i diagrammi di Venn in modo troppo ampio.
Sarà il

8

Un join interno restituisce righe che possono essere combinate in base ai criteri di join.
Un join esterno restituisce queste e tutte le righe ...
   ... dalla prima tabella per un join sinistro
   ... dalla seconda tabella per un join destro
   ... da entrambe le tabelle per un join completo

Scegliere quando usare l'uno o l'altro è una questione di determinare quali dati sono necessari. Per il tuo esempio, se hai bisogno solo dei record che hanno user_ids dal telefono che corrispondono agli ID dell'utente, usa il join interno. Se si desidera includere anche le righe dell'utente che non dispongono di una voce telefonica corrispondente, il join sinistro sarebbe appropriato.

Per ulteriori informazioni, consultare questa domanda su StackOverflow .


7

Se hai 2 tabelle come di seguito:

Table1 :   A1    B1          Table2  :    B2     C2 
           -     -                        -      -
           1     2                        1      1
           2     4                        2      4
           3     5                        5      2

Se usi Inner Join otterrai:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2

Se usi Full Outer Join otterrai:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2
 2      4    NULL     NULL
NULL   NULL    1       1

Se si utilizza Join esterno sinistro si ottiene:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2
 2      4    NULL     NULL

6

L'unione esterna è espressamente progettata per produrre valori nulli nel suo risultato e dovrebbe pertanto essere evitata, in generale. Relazionalmente parlando, è una specie di matrimonio con un fucile da caccia: costringe i tavoli a una sorta di unione - sì, intendo l'unione, non unirmi - anche quando i tavoli in questione non si conformano ai soliti requisiti per l'unione. Lo fa, in effetti, riempiendo di uno o entrambi i tavoli con valori null prima di fare l'unione, rendendoli così conformi a quei soliti requisiti dopo tutto. Ma non c'è motivo per cui quel padding non dovrebbe essere fatto con valori corretti anziché null, come in questo esempio:

SELECT SNO , PNO 
FROM   SP 
UNION  
SELECT SNO , 'nil' AS PNO 
FROM   S 
WHERE  SNO NOT IN ( SELECT SNO FROM SP )

In alternativa, è possibile ottenere lo stesso risultato utilizzando l'operatore di join esterno SQL in combinazione con COALESCE, come qui:

SELECT SNO , COALESCE ( PNO , 'nil' ) AS PNO 
FROM ( S NATURAL LEFT OUTER JOIN SP ) AS TEMP

Un commento sull'unione esterna (4.6) in "SQL e teoria relazionale: come scrivere codice SQL accurato" di CJ Date


5

Un join interno è un join in cui gli unici risultati visualizzati sono risultati in cui le chiavi si trovano in entrambe le tabelle. Un join esterno visualizzerà i risultati per tutti i tasti in una tabella, un join sinistro dal primo e un join destro dal secondo. Per esempio:

Supponiamo che table1 abbia le seguenti chiavi primarie e coppie di dati: (1, a), (2, b), (3, c)

Supponiamo anche che table2 abbia le seguenti chiavi primarie e coppie di dati: (1, fun), (3, can), (4, succede)

Quindi un join interno da table1 a table2 sulle chiavi primarie produrrebbe le seguenti terzine risultanti (con prima la chiave primaria comune, la seconda seconda voce della prima tabella e la terza seconda voce della seconda tabella): (1, a, fun), ( 3, c, can)

Un join esterno sinistro da table1 a table2 sulle chiavi primarie produrrebbe le seguenti terzine risultanti (stesso formato come sopra): (1, a, fun), (2, b, NULL), (3, c, can)

Un join esterno destro da table1 a table2 sulle chiavi primarie produrrebbe le seguenti terzine risultanti (stesso formato come sopra): (1, a, fun), (3, c, can), (4, NULL, succede)

Spero che questo spieghi bene il concetto.


4

Vorrei provare a descriverlo un po 'più intuitivo.

Il join interno mostra gli utenti che dispongono di uno o più telefoni insieme ai loro numeri di telefono.

Il join esterno sinistro elenca inoltre quegli "utenti" che non dispongono di telefono.


4

Dato che ti è stato chiesto quando utilizzare cosa, ecco uno scenario con query: seleziona quale utilizzare in base al requisito.

Dati:

Gli utenti della tabella ha 10 record. Tabella Phoneno ha 6 record (con una relazione 1: 1, il che significa che una voce in PhoneNo farà riferimento solo a una voce in Users, e solo una voce in PhoneNo può fare riferimento a una data voce in Users).

Requisito 1: mostra tutti gli utenti con i loro numeri di telefono. Ignora gli utenti senza numero di telefono.

Query:

SELECT u.uid, u.name, p.phonno 
  FROM user u 
INNER JOIN phones p ON p.uid = u.uid

Risultato: mostra 6 utenti che hanno un numero di telefono

Requisito 2: mostra tutti gli utenti con il loro numero di telefono. Se l'utente non ha un display del telefono 'N / A' (non disponibile)

Query:

SELECT u.uid, u.name, ifnull(p.phonno,'N/A') 
  FROM user u 
LEFT OUTER JOIN phones p ON p.uid = u.uid

Risultato:

Mostra tutti i 10 record

Nota: ifnull è una sintassi di MySql per trasformare il valore null. Ho usato questa funzione per fare in modo che il motore db mostrasse 'N / A' quando phonno è nullo. Cerca la funzione appropriata se stai usando qualche altro DBMS. In SQL Server devi usare l' CASEistruzione.

Spero che aiuti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.