MySQL: suddivisione rapida dei tipi di join


157

Vorrei una rapida suddivisione dei tipi di join MySQL. Conosco questi, il resto non sono sicuro di cosa significhino.

  • separati da virgola (che cosa significa esattamente questa abbreviazione?)SELECT * FROM a, b WHERE b.id = a.beeId AND ...
  • mostra le informazioni da a, anche se non ci sono corrispondenze in b: SELECT * FROM a LEFT OUTER JOIN b ON b.id = a.beeId WHERE ...

Ho visto altri join, ma voglio sapere cosa li rende diversi, cosa è INNER/ OUTER, fa LEFTcambiare le cose.

So già come funzionano i join, voglio solo sapere se esistono altri tipi di join o se sono solo modi diversi per ottenere lo stesso risultato.


Risposte:


463

3
+1 ma mancano entrambi cross join, il che fa un prodotto cartesiano.
Denis de Bernardy,

11
@denis: dai un'occhiata più da vicino al link codinghorror.com:There's also a cartesian product or cross join, which as far as I can tell, can't be expressed as a Venn diagram:
Rufinus,

1
Sono stupito, stampando questi schemi e mettendolo sul muro del mio ufficio. hai cambiato la mia vita!
Yossico,

41
La domanda riguarda in particolare MySQL. MySQL non supporta i join FULL OUTER.
Mike Baranczak,

4
e ovviamente questo dovrebbe essere un motivo per non pubblicare questo grafico. sospiro
Rufino

27

In base al tuo commento, le definizioni semplici di ciascuna sono reperibili in W3Schools La prima riga di ogni tipo fornisce una breve spiegazione del tipo di join

  • JOIN: restituisce le righe quando c'è almeno una corrispondenza in entrambe le tabelle
  • JOIN SINISTRA: restituisce tutte le righe dalla tabella di sinistra, anche se non ci sono corrispondenze nella tabella di destra
  • RIGHT JOIN: restituisce tutte le righe dalla tabella di destra, anche se non ci sono corrispondenze nella tabella di sinistra
  • FULL JOIN: restituisce le righe quando c'è una corrispondenza in una delle tabelle

MODIFICA FINE

In poche parole, l'esempio separato da virgola che hai dato

SELECT * FROM a, b WHERE b.id = a.beeId AND ...

sta selezionando ogni record dalle tabelle aeb con le virgole che separano le tabelle, questo può essere usato anche in colonne come

SELECT a.beeName,b.* FROM a, b WHERE b.id = a.beeId AND ...

Sta quindi ottenendo le informazioni fornite nella riga in cui la colonna b.id e la colonna a.beeId hanno una corrispondenza nell'esempio. Quindi nel tuo esempio otterrà tutte le informazioni dalle tabelle aeb dove b.id è uguale a a.beeId. Nel mio esempio otterrà tutte le informazioni dalla tabella b e solo le informazioni dalla colonna a.beeName quando b.id è uguale a a.beeId. Nota che esiste anche una clausola AND, che ti aiuterà a perfezionare i risultati.

Per alcuni semplici tutorial e spiegazioni sui join mySQL e sui join di sinistra, dai un'occhiata ai tutorial mySQL di Tizag. Puoi anche consultare il sito Web di Keith J. Brown per ulteriori informazioni sui join che è abbastanza buono.

Spero che questo ti aiuta


Succede che lo so già. In realtà stavo cercando i tipi di join che ci sono. Mi dispiace non essere stato chiaro su ciò che so già. Ma non stavo cercando una lunga documentazione solo per ottenere il breve riassunto.
Bryan Field,

Un altro riferimento nella risposta ... potrebbe essere più di quello che vuoi amico.
Ryan,

+1 per quella modifica. Non sono di parte nei confronti di W3Schools come alcune persone sembrano essere. Forse non ho visto molto i lati negativi o forse è solo una "guerra santa". Inoltre, ho modificato il contenuto di W3Schools, spero che non ti dispiaccia, ma sentiti libero di apportare qualsiasi modifica ti piaccia. Tutti questi elementi visivi nella risposta accettata sono belli, ma alcuni sono in realtà variazioni dello stesso join. Questa è una buona alternativa.
Bryan Field,

Grazie George, non mi dispiace affatto, a condizione che la modifica sia corretta! Sono convinto che le persone debbano trovare le fonti giuste per loro, più o meno informazioni, molti esempi o nessuno. Le scuole W3 sono accurate e concise, tendono anche ad avere buoni esempi, Tizag è simile. Take it easy compagno
Ryan

1
non c'è FULL JOIN in mysql, quindi questi link non sono molto utili.
Ether

13

Ho 2 tavoli come questo:

> SELECT * FROM table_a;
+------+------+
| id   | name |
+------+------+
|    1 | row1 |
|    2 | row2 |
+------+------+

> SELECT * FROM table_b;
+------+------+------+
| id   | name | aid  |
+------+------+------+
|    3 | row3 |    1 |
|    4 | row4 |    1 |
|    5 | row5 | NULL |
+------+------+------+

INNER JOIN si prende cura di entrambi i tavoli

INNER JOIN si prende cura di entrambi i tavoli, quindi otterrai una riga solo se entrambi i tavoli ne hanno uno. Se esiste più di una coppia corrispondente, si ottengono più righe.

> SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
+------+------+------+------+------+

INNER JOIN non fa differenza se inverti l'ordine, perché si preoccupa per entrambe le tabelle:

> SELECT * FROM table_b b INNER JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
+------+------+------+------+------+

Ottieni le stesse righe, ma le colonne sono in un ordine diverso perché abbiamo menzionato le tabelle in un ordine diverso.

LEFT JOIN si preoccupa solo del primo tavolo

LEFT JOIN si prende cura della prima tabella che gli dai, e non importa molto della seconda, quindi ottieni sempre le righe dalla prima tabella, anche se non c'è una riga corrispondente nella seconda:

> SELECT * FROM table_a a LEFT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
|    2 | row2 | NULL | NULL | NULL |
+------+------+------+------+------+

Sopra puoi vedere tutte le righe di table_a anche se alcune di esse non corrispondono a nulla nella tabella b, ma non tutte le righe di table_b - solo quelle che corrispondono a qualcosa in table_a.

Se invertiamo l'ordine delle tabelle, LEFT JOIN si comporta diversamente:

> SELECT * FROM table_b b LEFT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
|    5 | row5 | NULL | NULL | NULL |
+------+------+------+------+------+

Ora otteniamo tutte le righe di table_b, ma solo le righe corrispondenti di table_a.

RIGHT JOIN si preoccupa solo del secondo tavolo

a RIGHT JOIN bti dà esattamente le stesse file di b LEFT JOIN a. L'unica differenza è l'ordine predefinito delle colonne.

> SELECT * FROM table_a a RIGHT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
| NULL | NULL |    5 | row5 | NULL |
+------+------+------+------+------+

Queste sono le stesse righe table_b LEFT JOIN table_ache abbiamo visto nella sezione LEFT JOIN.

Allo stesso modo:

> SELECT * FROM table_b b RIGHT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
| NULL | NULL | NULL |    2 | row2 |
+------+------+------+------+------+

Ha le stesse righe di table_a LEFT JOIN table_b.

Nessuna partecipazione ti dà copie di tutto

Clausola No Join: se scrivi le tue tabelle senza alcuna clausola JOIN, separate solo da virgole, otterrai ogni riga della prima tabella scritta accanto a ogni riga della seconda tabella, in ogni possibile combinazione:

> SELECT * FROM table_b, table_a;        
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    3 | row3 | 1    |    2 | row2 |
|    4 | row4 | 1    |    1 | row1 |
|    4 | row4 | 1    |    2 | row2 |
|    5 | row5 | NULL |    1 | row1 |
|    5 | row5 | NULL |    2 | row2 |
+------+------+------+------+------+

(Questo è dal mio post sul blog Esempi di tipi di join SQL )


@Anu Per favore, non apportare modifiche così banali quando la tua bassa reputazione significa che le tue modifiche devono essere riviste da altri, stai solo perdendo tempo. Quella modifica avrebbe dovuto essere respinta come nessuna differenza. Il codice che hai cambiato non era effettivamente sbagliato e avresti potuto commentare.
philipxy

@philipxy Ok. Notato con quello. Mentre stavo cercando di capire la spiegazione, ho visto un tale errore di battitura ed è per questo che è stato modificato per renderlo più chiaro. In effetti questa è una buona risposta e la mia intenzione era di mantenerla più giusta.
Anu

@Anu Questa risposta ha le stesse descrizioni incomplete frammentate della maggior parte delle risposte. In realtà non dice quale sia l'output in funzione degli input. Vedi anche quasi tutte le risposte al duplicato proposto e i miei commenti su entrambe le pagine. Vedi anche la mia risposta lì. PS L'ho visto da un punto di vista monetario da ieri rivisto la dimensione di modifica (Naturalmente ci sono molti altri post correlati su Meta Stack Overflow & Meta Stack Exchange .)
philipxy

11

Il join esterno completo non esiste in mysql, potrebbe essere necessario utilizzare una combinazione di join destro e sinistro.

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.