Inoltre come si fa LEFT JOIN
, RIGHT JOIN
e FULL JOIN
in forma in?
Inoltre come si fa LEFT JOIN
, RIGHT JOIN
e FULL JOIN
in forma in?
Risposte:
Supponendo che ti unisci a colonne senza duplicati, il che è un caso molto comune:
Un'unione interna di A e B fornisce il risultato dell'intersezione A, ovvero la parte interna di un'intersezione del diagramma di Venn .
Un'unione esterna di A e B fornisce i risultati di un'unione B, ovvero le parti esterne di un'unione del diagramma di Venn.
Esempi
Supponiamo di avere due tabelle, ciascuna con una singola colonna e dati come segue:
A B
- -
1 3
2 4
3 5
4 6
Si noti che (1,2) sono univoci per A, (3,4) sono comuni e (5,6) sono univoci per B.
Join interno
Un join interno che utilizza una delle query equivalenti fornisce l'intersezione delle due tabelle, ovvero le due righe che hanno in comune.
select * from a INNER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b;
a | b
--+--
3 | 3
4 | 4
Unione esterna sinistra
Un join esterno sinistro fornirà tutte le righe in A, oltre a tutte le righe comuni in B.
select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b(+);
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
Unione esterna destra
Un join esterno destro fornirà tutte le righe in B, oltre a tutte le righe comuni in A.
select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a(+) = b.b;
a | b
-----+----
3 | 3
4 | 4
null | 5
null | 6
Join esterno completo
Un join esterno completo ti darà l'unione di A e B, cioè tutte le righe in A e tutte le righe in B. Se qualcosa in A non ha un dato corrispondente in B, allora la parte B è nulla e viceversa versa.
select * from a FULL OUTER JOIN b on a.a = b.b;
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
I diagrammi di Venn non lo fanno davvero per me.
Non mostrano alcuna distinzione tra un join incrociato e un join interno, ad esempio, o più in generale mostrano alcuna distinzione tra diversi tipi di predicato di join o forniscono una struttura per ragionare su come funzioneranno.
Non vi è alcun sostituto per comprendere l'elaborazione logica ed è relativamente semplice da afferrare comunque.
on
clausola rispetto a tutte le righe del passaggio 1 mantenendo quelle in cui il predicato valutatrue
(NB: in pratica, Query Optimizer può trovare modi più efficienti di eseguire la query rispetto alla descrizione puramente logica sopra, ma il risultato finale deve essere lo stesso)
Inizierò con una versione animata di un join esterno completo . Segue ulteriore spiegazione.
Tabelle di origine
Prima di tutto inizia con un CROSS JOIN
(prodotto cartesiano AKA). Questo non ha una ON
clausola e restituisce semplicemente ogni combinazione di righe dalle due tabelle.
SELEZIONA A.Colore, B.Colore DA UN CROSS JOIN B
I join interni ed esterni hanno un predicato della clausola "ON".
SELEZIONA A.Colore, B.Colore DA UN INTERNO UNISCI B SU A.Colore = B.Colore
Quanto sopra è il classico equi join.
La condizione di join interno non deve necessariamente essere una condizione di uguaglianza e non deve necessariamente fare riferimento a colonne di entrambe (o persino di entrambe) delle tabelle. La valutazione A.Colour NOT IN ('Green','Blue')
su ciascuna riga del cross join restituisce.
SELEZIONA A.Colore, B.Colore DA UN INTERNO UNISCI B SU 1 = 1
La condizione di join viene valutata come vera per tutte le righe nel risultato del join incrociato, quindi è uguale a un join incrociato. Non ripeterò di nuovo l'immagine delle 16 file.
I join esterni vengono logicamente valutati allo stesso modo dei join interni, tranne per il fatto che se una riga della tabella di sinistra (per un'unione di sinistra) non si unisce a nessuna riga della tabella di destra, viene preservata nel risultato con i NULL
valori per colonne di destra.
Questo limita semplicemente il risultato precedente per restituire solo le righe dove B.Colour IS NULL
. In questo caso particolare saranno le righe che sono state conservate in quanto non avevano corrispondenza nella tabella di destra e la query restituisce la singola riga rossa non corrispondente nella tabella B
. Questo è noto come anti semi join.
È importante selezionare una colonna per il IS NULL
test che non sia nullable o per la quale la condizione di join garantisce che eventuali NULL
valori vengano esclusi affinché questo modello funzioni correttamente ed eviti di riportare le righe che risultano avere un NULL
valore per quello colonna oltre alle righe non corrispondenti.
I join esterni di destra funzionano in modo simile ai join esterni di sinistra, tranne per il fatto che mantengono le righe non corrispondenti dalla tabella di destra e null estendono le colonne di sinistra.
I join esterni completi combinano il comportamento dei join sinistro e destro e preservano le righe non corrispondenti dalle tabelle sinistra e destra.
Nessuna riga nell'unione incrociata corrisponde al 1=0
predicato. Tutte le righe da entrambi i lati vengono conservate utilizzando le normali regole di join esterne con NULL nelle colonne della tabella sull'altro lato.
Con una modifica minore alla query precedente si potrebbe simulare una UNION ALL
delle due tabelle.
Si noti che la WHERE
clausola (se presente) viene eseguita logicamente dopo il join. Un errore comune è quello di eseguire un join esterno sinistro e quindi includere una clausola WHERE con una condizione sulla tabella destra che finisce escludendo le righe non corrispondenti. Quanto sopra finisce per eseguire il join esterno ...
... E poi viene eseguita la clausola "Where". NULL= 'Green'
non valuta come vero, quindi la riga conservata dal join esterno finisce scartata (insieme a quella blu) convertendo efficacemente il join in uno interno.
Se l'intenzione fosse quella di includere solo le righe da B in cui il colore è verde e tutte le righe da A indipendentemente dalla sintassi corretta sarebbe
Vedi questi esempi eseguiti dal vivo su SQLFiddle.com .
I join vengono utilizzati per combinare i dati di due tabelle, con il risultato che è una nuova tabella temporanea. I join vengono eseguiti in base a qualcosa chiamato predicato, che specifica la condizione da utilizzare per eseguire un join. La differenza tra un join interno e un join esterno è che un join interno restituirà solo le righe che corrispondono effettivamente in base al predicato del join. Ad esempio: prendiamo in considerazione la tabella Dipendente e Località:
Join interno: - Il join interno crea una nuova tabella dei risultati combinando i valori di colonna di due tabelle ( Employee e Location ) in base al predicato di join. La query confronta ogni riga del Dipendente con ciascuna riga di Location per trovare tutte le coppie di righe che soddisfano il predicato di join. Quando il predicato di join viene soddisfatto abbinando valori non NULL, i valori di colonna per ciascuna coppia di righe di Employee e Location corrispondenti vengono combinati in una riga di risultato. Ecco come apparirà l'SQL per un join interno:
select * from employee inner join location on employee.empID = location.empID
OR
select * from employee, location where employee.empID = location.empID
Ora, ecco come sarebbe il risultato dell'esecuzione di quell'SQL:
Join esterno: - Un join esterno non richiede che ogni record nelle due tabelle unite abbia un record corrispondente. La tabella unita conserva ogni record, anche se non esiste nessun altro record corrispondente. I join esterni si suddividono ulteriormente in join esterni a sinistra e join esterni a destra, a seconda delle righe della tabella mantenute (sinistra o destra).
Join esterno sinistro: - Il risultato di un join esterno sinistro (o semplicemente un join sinistro) per le tabelle Employee e Location contiene sempre tutti i record della tabella "left" ( Employee ), anche se la condizione di join non trova alcun record corrispondente in la tabella "giusta" ( posizione ). Ecco come sarebbe l'SQL per un join esterno sinistro, usando le tabelle sopra:
select * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional
Ora, ecco come sarebbe il risultato dell'esecuzione di questo SQL:
Unione esterna destra: - Un'unione esterna destra (o unione destra) ricorda da vicino un'unione esterna sinistra, tranne per il trattamento delle tabelle invertito. Ogni riga della tabella "destra" ( Posizione ) apparirà nella tabella unita almeno una volta. Se non esiste alcuna riga corrispondente dalla tabella "sinistra" ( Dipendente ), NULL apparirà in colonne da Dipendente per quei record che non hanno corrispondenza in Posizione . Ecco come appare l'SQL:
select * from employee right outer join location on employee.empID = location.empID;
//Use of outer keyword is optional
Usando le tabelle sopra, possiamo mostrare come sarebbe il set di risultati di un join esterno destro:
Join esterni completi : - Join esterni completi o Join completi per conservare le informazioni non corrispondenti includendo le righe non corrispondenti nei risultati di un join, utilizzare un join esterno completo. Include tutte le righe di entrambe le tabelle, indipendentemente dal fatto che l'altra tabella abbia o meno un valore corrispondente.
Manuale di riferimento di MySQL 8.0 - Partecipa alla sintassi
Recupera solo le righe corrispondenti, ovvero A intersect B
.
SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
Seleziona tutti i record dalla prima tabella e tutti i record nella seconda tabella che corrispondono alle chiavi unite.
SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
Seleziona tutti i record dalla seconda tabella e tutti i record nella prima tabella che corrispondono alle chiavi unite.
SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
In parole semplici:
Un'unione interiore recupera solo le righe corrispondenti.
Considerando che un join esterno recupera le righe corrispondenti da una tabella e tutte le righe nell'altra tabella .... il risultato dipende da quale si sta utilizzando:
Sinistra : righe corrispondenti nella tabella di destra e tutte le righe nella tabella di sinistra
Destra : righe corrispondenti nella tabella di sinistra e tutte le righe nella tabella di destra o
Completo : tutte le righe in tutte le tabelle. Non importa se c'è una partita o no
Un join interno mostra le righe solo se è presente un record corrispondente sull'altro lato (destro) del join.
Un join esterno (sinistro) mostra le righe per ciascun record sul lato sinistro, anche se non vi sono righe corrispondenti sull'altro lato (destro) del join. Se non ci sono righe corrispondenti, le colonne per l'altro lato (destro) mostreranno NULL.
I join interni richiedono l'esistenza di un record con un ID correlato nella tabella unita.
I join esterni restituiranno i record per il lato sinistro anche se non esiste nulla per il lato destro.
Ad esempio, hai una tabella Orders e OrderDetails. Sono collegati da un "OrderID".
Ordini
OrderDetails
La richiesta
SELECT Orders.OrderID, Orders.CustomerName
FROM Orders
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
restituirà solo gli ordini che hanno anche qualcosa nella tabella OrderDetails.
Se lo cambi in ESTERNO SINISTRA UNISCITI
SELECT Orders.OrderID, Orders.CustomerName
FROM Orders
LEFT JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
quindi restituirà i record dalla tabella Ordini anche se non hanno record OrderDetails.
Puoi usarlo per trovare ordini che non hanno alcun OrderDetails che indica un possibile ordine orfano aggiungendo una clausola where WHERE OrderDetails.OrderID IS NULL
.
SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c, categories_description cd WHERE c.id = cd.categories_id AND c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC
a SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c INNER JOIN categories_description cd ON c.id = cd.categories_id WHERE c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC
(MySQL) con successo. Non ero sicuro delle condizioni aggiuntive, si mescolano bene ...
In parole semplici:
Join interno -> Prendi SOLO i record comuni dalle tabelle padre e figlio DOVE la chiave primaria della tabella padre corrisponde alla chiave esterna nella tabella figlio.
Join sinistro ->
pseudo codice
1.Take All records from left Table
2.for(each record in right table,) {
if(Records from left & right table matching on primary & foreign key){
use their values as it is as result of join at the right side for 2nd table.
} else {
put value NULL values in that particular record as result of join at the right side for 2nd table.
}
}
Unisciti a destra : esattamente opposto rispetto al join sinistro. Inserisci il nome della tabella in LEFT JOIN sul lato destro in Right join, otterrai lo stesso output di LEFT JOIN.
Join esterno : mostra tutti i record in entrambe le tabelleNo matter what
. Se i record nella tabella di sinistra non corrispondono alla tabella di destra in base alla chiave primaria, Forieign, utilizzare il valore NULL come risultato del join.
Esempio :
Supponiamo ora per 2 tavoli
1.employees , 2.phone_numbers_employees
employees : id , name
phone_numbers_employees : id , phone_num , emp_id
Qui, la tabella degli impiegati è la tabella principale, phone_numbers_employees è la tabella figlio (contiene emp_id
come chiave esterna che si collega employee.id
quindi la sua tabella figlio).
Join interni
Prendi i record di 2 tabelle SOLO SE La chiave primaria della tabella degli impiegati (il suo ID) corrisponde alla chiave esterna della tabella figlio phone_numbers_employees (emp_id) .
Quindi la query sarebbe:
SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
Qui prendi solo le righe corrispondenti sulla chiave primaria = chiave esterna come spiegato sopra. Qui le righe non corrispondenti sulla chiave primaria = chiave esterna vengono saltate come risultato del join.
Join di sinistra :
Il join sinistro mantiene tutte le righe della tabella di sinistra, indipendentemente dal fatto che vi sia una riga corrispondente nella tabella di destra.
SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
Join esterni :
SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
Diagrammaticamente sembra:
Si utilizza INNER JOIN
per restituire tutte le righe da entrambe le tabelle in cui esiste una corrispondenza. cioè nella tabella risultante tutte le righe e le colonne avranno valori.
Nella OUTER JOIN
tabella risultante possono essere presenti colonne vuote. L'unione esterna può essere LEFT
o RIGHT
.
LEFT OUTER JOIN
restituisce tutte le righe dalla prima tabella, anche se non vi sono corrispondenze nella seconda tabella.
RIGHT OUTER JOIN
restituisce tutte le righe dalla seconda tabella, anche se non ci sono corrispondenze nella prima tabella.
Questa è una buona spiegazione schematica per tutti i tipi di join
fonte: http://ssiddique.info/understanding-sql-joins-in-easy-way.html
INNER JOIN
richiede almeno una corrispondenza nel confronto tra le due tabelle. Ad esempio, la tabella A e la tabella B che implica A ٨ B (intersezione A B).
LEFT OUTER JOIN
e LEFT JOIN
sono uguali. Fornisce tutti i record corrispondenti in entrambe le tabelle e tutte le possibilità della tabella di sinistra.
Allo stesso modo, RIGHT OUTER JOIN
e RIGHT JOIN
sono gli stessi. Fornisce tutti i record corrispondenti in entrambe le tabelle e tutte le possibilità della tabella giusta.
FULL JOIN
è la combinazione di LEFT OUTER JOIN
e RIGHT OUTER JOIN
senza duplicazione.
La risposta è nel significato di ciascuno, quindi nei risultati.
Nota:
InSQLite
non c'èRIGHT OUTER JOIN
oFULL OUTER JOIN
.
E anche dentroMySQL
non c'èFULL OUTER JOIN
.
La mia risposta si basa sulla nota sopra .
Quando hai due tavoli come questi:
--[table1] --[table2]
id | name id | name
---+------- ---+-------
1 | a1 1 | a2
2 | b1 3 | b2
CROSS JOIN / OUTER JOIN:
puoi avere tutti quei dati delle tabelle con CROSS JOIN
o semplicemente con ,
questo:
SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2
--[Results:]
id | name | id | name
---+------+----+------
1 | a1 | 1 | a2
1 | a1 | 3 | b2
2 | b1 | 1 | a2
2 | b1 | 3 | b2
INNER JOIN:
quando si desidera aggiungere un filtro ai risultati sopra basati su una relazione come table1.id = table2.id
è possibile utilizzare INNER JOIN
:
SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id
--[Results:]
id | name | id | name
---+------+----+------
1 | a1 | 1 | a2
LEFT [OUTER] JOIN:
Quando vuoi avere tutte le righe di una delle tabelle nel risultato sopra -con la stessa relazione- puoi usare LEFT JOIN
:
(Per JOIN RIGHT basta cambiare il posto delle tabelle)
SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
--[Results:]
id | name | id | name
---+------+------+------
1 | a1 | 1 | a2
2 | b1 | Null | Null
UNISCITI ESTERNI COMPLETI:
quando vuoi avere anche tutte le righe dell'altra tabella nei tuoi risultati puoi usare FULL OUTER JOIN
:
SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id
--[Results:]
id | name | id | name
-----+------+------+------
1 | a1 | 1 | a2
2 | b1 | Null | Null
Null | Null | 3 | b2
Bene, in base alle tue necessità, scegli ognuna che copra le tue necessità;).
full outer join
MySQL è presente .
Join interno.
Un join sta combinando le righe da due tabelle. Un join interno tenta di abbinare le due tabelle in base ai criteri specificati nella query e restituisce solo le righe corrispondenti. Se una riga della prima tabella nel join corrisponde a due righe nella seconda tabella, nei risultati verranno restituite due righe. Se c'è una riga nella prima tabella che non corrisponde a una riga nella seconda, non viene restituita; allo stesso modo, se c'è una riga nella seconda tabella che non corrisponde a una riga nella prima, non viene restituita.
Join esterno.
Un join sinistro tenta di trovare la corrispondenza tra le righe della prima tabella e le righe della seconda tabella. Se non riesce a trovare una corrispondenza, restituirà le colonne della prima tabella e lascerà vuote le colonne della seconda tabella (null).
INNER JOIN
join più tipico per due o più tabelle. Restituisce la corrispondenza dei dati su entrambi tabella ON chiave primaria e relazione forignkey.OUTER JOIN
è uguale a INNER JOIN
, ma include anche i NULL
dati su ResultSet.
LEFT JOIN
= INNER JOIN
+ Dati ineguagliati della tabella di sinistra con Null
corrispondenza sulla tabella di destra.RIGHT JOIN
= INNER JOIN
+ Dati senza pari della tabella destra conNull
corrispondenza sulla tabella di sinistra.FULL JOIN
= INNER JOIN
+ Dati senza eguali su entrambe le tabelle destra e sinistra con Null
corrispondenze.INNER JOIN
e OUTER JOIN
possiamo scrivere query di auto-join.Per esempio:
SELECT *
FROM tablea a
INNER JOIN tableb b
ON a.primary_key = b.foreign_key
INNER JOIN tablec c
ON b.primary_key = c.foreign_key
Non vedo molti dettagli sulle prestazioni e sull'ottimizzatore nelle altre risposte.
A volte è bene saperlo solo INNER JOIN
è associativo, il che significa che l'ottimizzatore ha più possibilità di giocarci. Può riordinare l'ordine di join per renderlo più veloce mantenendo lo stesso risultato. L'ottimizzatore può utilizzare la maggior parte delle modalità di join.
Generalmente è una buona pratica provare a utilizzare al INNER JOIN
posto del diverso tipo di join. (Naturalmente se è possibile considerando il set di risultati attesi.)
Ci sono un paio di buoni esempi e spiegazioni qui su questo strano comportamento associativo:
INNER JOIN
è più lento che LEFT JOIN
nella maggior parte delle volte, e le persone possono usare LEFT JOIN
invece di INNER JOIN
aggiungere un WHERE
per rimuovere NULL
risultati imprevisti ;).
INNER
sia più lento?
Dopo aver criticato il tanto amato diagramma di Venn in rosso, ho pensato che fosse giusto pubblicare il mio tentativo.
Sebbene la risposta di @Martin Smith sia di gran lunga la migliore di questo gruppo, mostra solo la colonna chiave di ogni tabella, mentre penso che anche le colonne idealmente non chiave dovrebbero essere mostrate.
Il meglio che potrei fare nella mezz'ora consentita, non penso ancora che mostri adeguatamente che i valori null sono lì a causa dell'assenza di valori chiave TableB
o che in OUTER JOIN
realtà è un'unione piuttosto che un'unione:
TableA a LEFT OUTER JOIN TableB b
conTableB B RIGHT OUTER JOIN TableA a
L'algoritmo preciso per INNER JOIN
, LEFT/RIGHT OUTER JOIN
sono i seguenti:
a
(a, b[i])
ON ...
clausola rispetto a ciascuna coppia:ON( a, b[i] ) = true/false?
true
restituisce, restituisce quella riga combinata (a, b[i])
.Outer Join
quindi di restituire una coppia (virtuale) usando Null
per tutte le colonne dell'altra tabella: (a, Null)
per il join esterno SINISTRA o il (Null, b)
join esterno DESTRO. Questo per garantire che tutte le righe della prima tabella esistano nei risultati finali.Nota: la condizione specificata nella ON
clausola potrebbe essere qualsiasi cosa, non è necessario utilizzare le chiavi primarie (e non è necessario fare sempre riferimento alle colonne di entrambe le tabelle)! Per esempio:
... ON T1.title = T2.title AND T1.version < T2.version
(=> vedi questo post come esempio di utilizzo: seleziona solo le righe con il valore massimo su una colonna )... ON T1.y IS NULL
... ON 1 = 0
(proprio come campione)Nota: Join sinistro = Join esterno sinistro, Join destro = Join esterno destro.
Definizioni più semplici
Inner Join: restituisce i record corrispondenti da entrambe le tabelle.
Join esterno completo: restituisce i record corrispondenti e non corrispondenti di entrambe le tabelle con null per i record non corrispondenti di entrambe le tabelle .
Join esterno sinistro: restituisce i record corrispondenti e non corrispondenti solo dalla tabella sul lato sinistro .
Join esterno destro: restituisce i record corrispondenti e non corrispondenti solo dalla tabella sul lato destro .
In breve
Corrispondenza + sinistra senza corrispondenza + destra senza corrispondenza = unione esterna completa
Matched + Left Unmatched = Join esterno sinistro
Matched + Right Unmatched = Right Outer Join
Abbinato = Join interno
In parole povere,
1. JOIN INNER O JOIN EQUI: restituisce il gruppo di risultati che corrisponde solo alla condizione in entrambe le tabelle.
2. OUTER JOIN: restituisce il set di risultati di tutti i valori da entrambe le tabelle anche se esiste una corrispondenza delle condizioni o meno.
3. JOIN SINISTRA: restituisce il set di risultati di tutti i valori dalla tabella a sinistra e solo le righe che corrispondono alla condizione nella tabella a destra.
4. JOIN DESTRO: restituisce il set di risultati di tutti i valori dalla tabella di destra e solo le righe che corrispondono alla condizione nella tabella di sinistra.
5. JOIN COMPLETO: Full Join e Full outer Join sono uguali.
Esempi
Supponiamo di avere due tabelle, ciascuna con una singola colonna e dati come segue:
A B
- -
1 3
2 4
3 5
4 6
7
8
Si noti che (1,2,7,8) sono unici per A, (3,4) sono comuni e (5,6) sono unici per B.
La parola chiave INNER JOIN seleziona tutte le righe da entrambe le tabelle purché la condizione soddisfi. Questa parola chiave creerà il set di risultati combinando tutte le righe di entrambe le tabelle in cui la condizione soddisfa, ovvero il valore del campo comune sarà lo stesso.
select * from a INNER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b;
Risultato:
a | b
--+--
3 | 3
4 | 4
Questo join restituisce tutte le righe della tabella sul lato sinistro del join e le righe corrispondenti per la tabella sul lato destro del join. Le righe per le quali non esiste una riga corrispondente sul lato destro, il set di risultati conterrà null. LEFT JOIN è anche noto come LEFT OUTER JOIN
.
select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b(+);
Risultato:
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
7 | null
8 | null
select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a(+) = b.b;
Risultato:
a | b
-----+----
3 | 3
4 | 4
null | 5
null | 6
FULL (ESTERNO) ISCRIVITI :
FULL JOIN crea il set di risultati combinando il risultato di LEFT JOIN e RIGHT JOIN. Il set di risultati conterrà tutte le righe di entrambe le tabelle. Le righe per le quali non esiste corrispondenza, il set di risultati conterrà valori NULL.
select * from a FULL OUTER JOIN b on a.a = b.b;
Risultato:
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
7 | null
8 | null
Join interno : un join interno che utilizza una delle query equivalenti fornisce l'intersezione delle due tabelle , ovvero le due righe che hanno in comune.
Join esterno sinistro : un join esterno sinistro fornirà tutte le righe in A, oltre a tutte le righe comuni in B.
Join esterno completo : un join esterno completo fornisce l'unione di A e B, ovvero tutte le righe in A e tutte le righe in B. Se qualcosa in A non ha un dato corrispondente in B, la porzione B è null e viceversa
Join is not an intersection unless the tables have the same columns
No. Puoi unire tutte le colonne che desideri e se il valore corrisponde, si uniranno.
1. Inner Join: chiamato anche come Join. Restituisce le righe presenti sia nella tabella di sinistra, sia nella tabella di destra solo se esiste una corrispondenza . Altrimenti, restituisce zero record.
Esempio:
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
INNER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
2. Join esterno completo: chiamato anche Full Join. Restituisce tutte le righe presenti nella tabella di sinistra e nella tabella di destra.
Esempio:
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
FULL OUTER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
3. Join esterno sinistro: Join o semplicemente chiamato come Join sinistro. Restituisce tutte le righe presenti nella tabella di sinistra e le righe corrispondenti dalla tabella di destra (se presenti).
4. Join esterno destro: chiamato anche come join destro. Restituisce le righe corrispondenti dalla tabella di sinistra (se presente) e tutte le righe presenti nella tabella di destra.
Vantaggi dei join
Considera di seguito 2 tabelle:
EMP
empid name dept_id salary
1 Rob 1 100
2 Mark 1 300
3 John 2 100
4 Mary 2 300
5 Bill 3 700
6 Jose 6 400
Dipartimento
deptid name
1 IT
2 Accounts
3 Security
4 HR
5 R&D
Principalmente scritto come JOIN nelle query sql. Restituisce solo i record corrispondenti tra le tabelle.
Select a.empid, a.name, b.name as dept_name
FROM emp a
JOIN department b
ON a.dept_id = b.deptid
;
empid name dept_name
1 Rob IT
2 Mark IT
3 John Accounts
4 Mary Accounts
5 Bill Security
Come vedete sopra, Jose
non viene stampata dalla EMP nell'output quanto di dept_id 6
non trova una corrispondenza nella tabella dipartimento. Allo stesso modo, HR
e le R&D
righe non vengono stampate dalla tabella Department poiché non hanno trovato una corrispondenza nella tabella Emp.
Quindi, INNER JOIN o semplicemente JOIN, restituisce solo le righe corrispondenti.
Ciò restituisce tutti i record dalla tabella SINISTRA e solo i record corrispondenti dalla tabella DESTRA.
Select a.empid, a.name, b.name as dept_name
FROM emp a
LEFT JOIN department b
ON a.dept_id = b.deptid
;
empid name dept_name
1 Rob IT
2 Mark IT
3 John Accounts
4 Mary Accounts
5 Bill Security
6 Jose
Pertanto, se si osserva l'output sopra riportato, tutti i record della tabella LEFT (Emp) vengono stampati con solo i record corrispondenti della tabella DESTRA.
HR
e le R&D
righe non vengono stampate dalla tabella Department poiché non hanno trovato una corrispondenza nella tabella Emp su dept_id.
Quindi, SINISTRA SINISTRA restituisce TUTTE le righe dalla tabella sinistra e solo le righe corrispondenti dalla tabella DESTRA.
Puoi anche controllare DEMO qui .
Si prega di consultare la risposta di Martin Smith per una migliore spiegazione e spiegazione dei diversi join, comprese e in particolare le differenze tra FULL OUTER JOIN
, RIGHT OUTER JOIN
e LEFT OUTER JOIN
.
Queste due tabelle costituiscono una base per la rappresentazione delle JOIN
seguenti:
SELECT *
FROM citizen
CROSS JOIN postalcode
Il risultato saranno i prodotti cartesiani di tutte le combinazioni. Nessuna JOIN
condizione richiesta:
INNER JOIN
è uguale al semplice: JOIN
SELECT *
FROM citizen c
JOIN postalcode p ON c.postal = p.postal
Il risultato saranno combinazioni che soddisfano la JOIN
condizione richiesta :
LEFT OUTER JOIN
equivale a LEFT JOIN
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
Il risultato sarà tutto, citizen
anche se non ci sono partite in postalcode
. Ancora una volta JOIN
è richiesta una condizione:
Tutti gli esempi sono stati eseguiti su un Oracle 18c. Sono disponibili su dbfiddle.uk, che è anche il luogo di provenienza degli screenshot dei tavoli.
CREATE TABLE citizen (id NUMBER,
name VARCHAR2(20),
postal NUMBER, -- <-- could do with a redesign to postalcode.id instead.
leader NUMBER);
CREATE TABLE postalcode (id NUMBER,
postal NUMBER,
city VARCHAR2(20),
area VARCHAR2(20));
INSERT INTO citizen (id, name, postal, leader)
SELECT 1, 'Smith', 2200, null FROM DUAL
UNION SELECT 2, 'Green', 31006, 1 FROM DUAL
UNION SELECT 3, 'Jensen', 623, 1 FROM DUAL;
INSERT INTO postalcode (id, postal, city, area)
SELECT 1, 2200, 'BigCity', 'Geancy' FROM DUAL
UNION SELECT 2, 31006, 'SmallTown', 'Snizkim' FROM DUAL
UNION SELECT 3, 31006, 'Settlement', 'Moon' FROM DUAL -- <-- Uuh-uhh.
UNION SELECT 4, 78567390, 'LookoutTowerX89', 'Space' FROM DUAL;
JOIN
eWHERE
CROSS JOIN
risultante in righe come L'idea generale / INNER JOIN
:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows
Utilizzare CROSS JOIN
per ottenere il risultato di un LEFT OUTER JOIN
richiede trucchi come l'aggiunta in una NULL
riga. È stato omesso.
INNER JOIN
diventa un prodotto cartesiano. È lo stesso di The General Idea / CROSS JOIN
:
SELECT *
FROM citizen c
JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN
È qui che il join interno può davvero essere visto come il join incrociato con risultati che non corrispondono alla condizione rimossa. Qui nessuna delle righe risultanti viene rimossa.
Usare INNER JOIN
per ottenere il risultato di un LEFT OUTER JOIN
richiede anche dei trucchi. È stato omesso.
LEFT JOIN
risulta nelle righe come L'idea generale / CROSS JOIN
:
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN
LEFT JOIN
risulta nelle righe come L'idea generale / INNER JOIN
:
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
WHERE p.postal IS NOT NULL -- < -- removed the row where there's no mathcing result from postalcode
Una ricerca di immagini su "sql join cross inner external" mostrerà una moltitudine di diagrammi di Venn. Avevo una copia stampata di uno sulla mia scrivania. Ma ci sono problemi con la rappresentazione.
Il diagramma di Venn è eccellente per la teoria degli insiemi, in cui un elemento può trovarsi in uno o entrambi gli insiemi. Ma per i database, un elemento in un "set" mi sembra una riga in una tabella e quindi non è presente in nessuna altra tabella. Non esiste una riga presente in più tabelle. Una riga è unica per la tabella.
I self join sono un caso angolare in cui ogni elemento è in effetti lo stesso in entrambi i set. Ma non è ancora libero da nessuno dei problemi di seguito.
L'insieme A
rappresenta l'insieme a sinistra (la citizen
tabella) e l'insieme B
è l'insieme a destra (la postalcode
tabella) nella discussione di seguito.
Ogni elemento di entrambi gli insiemi è abbinato a ogni elemento dell'altro insieme, il che significa che abbiamo bisogno di A
quantità di ogni B
elemento e B
quantità di ogni A
elemento per rappresentare correttamente questo prodotto cartesiano. La teoria degli insiemi non è fatta per più elementi identici in un insieme, quindi trovo che i diagrammi di Venn rappresentino correttamente impraticabile / impossibile. Non sembra che si UNION
adatti affatto.
Le righe sono distinte. Sono UNION
7 righe in totale. Ma sono incompatibili per un SQL
set di risultati comune . E non è affatto così che CROSS JOIN
funziona:
Cercando di rappresentarlo in questo modo:
..ma ora sembra proprio come una INTERSECTION
, che è certamente non è . Inoltre non vi è alcun elemento nel fatto INTERSECTION
che si trova effettivamente in nessuno dei due set distinti. Tuttavia, assomiglia molto ai risultati della ricerca simili a questo:
Per riferimento un risultato ricercabile per CROSS JOIN
s può essere visto su Tutorialgateway . Il INTERSECTION
, proprio come questo, è vuoto.
Il valore di un elemento dipende dalla JOIN
condizione. È possibile rappresentarlo a condizione che ogni riga diventi unica per quella condizione. Il significato id=x
è vero solo per una riga. Una volta che una riga nella tabella A
( citizen
) corrisponde a più righe nella tabella B
( postalcode
) nella JOIN
condizione, il risultato presenta gli stessi problemi del CROSS JOIN
: La riga deve essere rappresentata più volte e la teoria degli insiemi non è fatta per questo. Nella condizione di unicità, il diagramma potrebbe funzionare, ma tieni presente che la JOIN
condizione determina il posizionamento di un elemento nel diagramma. Osservando solo i valori della JOIN
condizione con il resto della riga, giusto per la corsa:
Questa rappresentazione cade completamente a pezzi quando si usa un INNER JOIN
con una ON 1 = 1
condizione che lo trasforma in a CROSS JOIN
.
Con un self- JOIN
, le righe sono in realtà elementi identici in entrambe le tabelle, ma rappresentano le tabelle come entrambe A
e B
non sono molto adatte. Ad esempio, una JOIN
condizione autonoma comune che fa in modo che un elemento A
corrisponda a un elemento diverso in B è ON A.parent = B.child
, facendo la corrispondenza da A
a B
elementi separati. Dagli esempi che sarebbe SQL
simile a questo:
SELECT *
FROM citizen c1
JOIN citizen c2 ON c1.id = c2.leader
Significa che Smith è il leader di Green e Jensen.
Ancora una volta i problemi iniziano quando una riga ha più corrispondenze con le righe nell'altra tabella. Ciò è ulteriormente complicato perché si OUTER JOIN
può pensare che corrisponda all'insieme vuoto. Ma nella teoria degli insiemi l'unione di qualsiasi insieme C
e un insieme vuoto è sempre giusta C
. Il set vuoto non aggiunge nulla. La rappresentazione di questo di LEFT OUTER JOIN
solito mostra solo tutto A
per illustrare che le righe A
sono selezionate indipendentemente dal fatto che ci sia o meno una corrispondenza B
. Gli "elementi corrispondenti" presentano tuttavia gli stessi problemi dell'illustrazione sopra. Dipendono dalla condizione. E il set vuoto sembra aver vagato per A
:
Trovare tutte le righe da a CROSS JOIN
con Smith e il codice postale sulla Luna:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
AND p.area = 'Moon';
Ora il diagramma di Venn non viene utilizzato per riflettere il JOIN
. È usato solo per la WHERE
clausola:
..e questo ha senso.
Come spiegato an INNER JOIN
non è proprio un INTERSECT
. Tuttavia, INTERSECT
è possibile utilizzare s sui risultati di query separate. Qui un diagramma di Venn ha senso, perché gli elementi delle query separate sono in realtà righe che appartengono solo a uno dei risultati o entrambi. Intersect ovviamente restituirà risultati solo se la riga è presente in entrambe le query. Ciò SQL
comporterà la stessa riga di quella sopra WHERE
e anche il diagramma di Venn sarà lo stesso:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
INTERSECT
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE p.area = 'Moon';
An OUTER JOIN
non è un UNION
. Tuttavia, UNION
lavorare nelle stesse condizioni di INTERSECT
, risultando in un ritorno di tutti i risultati combinando entrambi i SELECT
s:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
UNION
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE p.area = 'Moon';
che equivale a:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
OR p.area = 'Moon';
..e dà il risultato:
Anche qui un diagramma di Venn ha senso:
Una nota importante è che funzionano solo quando la struttura dei risultati dei due SELECT è la stessa, consentendo un confronto o unione. I risultati di questi due non consentiranno che:
SELECT *
FROM citizen
WHERE name = 'Smith'
SELECT *
FROM postalcode
WHERE area = 'Moon';
.. provare a combinare i risultati con UNION
dà a
ORA-01790: expression must have same datatype as corresponding expression
Per ulteriore interesse, leggi Dì NO ai diagrammi di Venn quando spieghi i JOIN e i join sql come diagramma di Venn . Entrambi coprono anche EXCEPT
.
Ci sono molte buone risposte qui con esempi di algebra relazionale molto accurati . Ecco una risposta molto semplificata che potrebbe essere utile per i programmatori dilettanti o principianti con dilemmi di codifica SQL.
Fondamentalmente, il più delle volte, le query JOIN
si riducono a due casi:
Per un SELECT
sottoinsieme di dati A
:
INNER JOIN
quando i dati correlati che B
si stanno cercando DEVONO esistere per la progettazione del database;LEFT JOIN
quando i dati correlati che B
si stanno cercando POTREBBE o POTREBBE NON esistere per la progettazione del database.La differenza tra inner join
e outer join
è la seguente:
Inner join
è un join che combina tabelle basate su tuple corrispondenti, mentre outer join
è un join che combina tabelle basate su tuple abbinate e non corrispondenti.Inner join
unisce le righe corrispondenti da due tabelle in cui vengono omesse le righe senza corrispondenza, mentre outer join
unisce le righe da due tabelle e le righe senza corrispondenza si riempiono di valore null.Inner join
è come un'operazione di intersezione, mentre outer join
è come un'operazione di unione.Inner join
sono due tipi, mentre outer join
sono tre tipi.outer join
è più veloce di inner join
.