Questa è una domanda molto comune, quindi questa risposta si basa su questo articolo che ho scritto.
Relazione al tavolo
Considerando che abbiamo le seguenti post
e le post_comment
tabelle:
L' post
ha i seguenti record:
| id | title |
|----|-----------|
| 1 | Java |
| 2 | Hibernate |
| 3 | JPA |
e il post_comment
ha le seguenti tre righe:
| id | review | post_id |
|----|-----------|---------|
| 1 | Good | 1 |
| 2 | Excellent | 1 |
| 3 | Awesome | 2 |
SQL INNER JOIN
La clausola JOIN SQL consente di associare righe appartenenti a tabelle diverse. Ad esempio, a CROSS JOIN creerà un prodotto cartesiano contenente tutte le possibili combinazioni di righe tra le due tabelle di giunzione.
Mentre CROSS JOIN è utile in alcuni scenari, la maggior parte delle volte, si desidera unire le tabelle in base a una condizione specifica. Ed è qui che entra in gioco INNER JOIN.
SQL INNER JOIN ci consente di filtrare il prodotto cartesiano dall'unione di due tabelle in base a una condizione specificata tramite la clausola ON.
SQL INNER JOIN - ON condizione "sempre vera"
Se si fornisce una condizione "sempre vera", INNER JOIN non filtrerà i record uniti e il set di risultati conterrà il prodotto cartesiano delle due tabelle di unione.
Ad esempio, se eseguiamo la seguente query SQL INNER JOIN:
SELECT
p.id AS "p.id",
pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 1
Otterremo tutte le combinazioni post
e i post_comment
record:
| p.id | pc.id |
|---------|------------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
Pertanto, se la condizione della clausola ON è "sempre vera", INNER JOIN è semplicemente equivalente a una query CROSS JOIN:
SELECT
p.id AS "p.id",
pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 1
ORDER BY p.id, pc.id
SQL INNER JOIN - ON Condizione "sempre falso"
D'altra parte, se la condizione della clausola ON è "sempre falsa", tutti i record uniti verranno filtrati e il set di risultati sarà vuoto.
Quindi, se eseguiamo la seguente query SQL INNER JOIN:
SELECT
p.id AS "p.id",
pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 0
ORDER BY p.id, pc.id
Non otterremo alcun risultato indietro:
| p.id | pc.id |
|---------|------------|
Questo perché la query sopra è equivalente alla seguente query CROSS JOIN:
SELECT
p.id AS "p.id",
pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 0
ORDER BY p.id, pc.id
SQL INNER JOIN - clausola ON che utilizza le colonne Chiave esterna e Chiave primaria
La condizione della clausola ON più comune è quella che corrisponde alla colonna Chiave esterna nella tabella figlio con la colonna Chiave primaria nella tabella padre, come illustrato dalla seguente query:
SELECT
p.id AS "p.id",
pc.post_id AS "pc.post_id",
pc.id AS "pc.id",
p.title AS "p.title",
pc.review AS "pc.review"
FROM post p
INNER JOIN post_comment pc ON pc.post_id = p.id
ORDER BY p.id, pc.id
Quando si esegue la query SQL INNER JOIN sopra riportata, si ottiene il seguente set di risultati:
| p.id | pc.post_id | pc.id | p.title | pc.review |
|---------|------------|------------|------------|-----------|
| 1 | 1 | 1 | Java | Good |
| 1 | 1 | 2 | Java | Excellent |
| 2 | 2 | 3 | Hibernate | Awesome |
Pertanto, solo i record che corrispondono alla condizione della clausola ON sono inclusi nel set di risultati della query. Nel nostro caso, il set di risultati contiene tutte le post
insieme con i loro post_comment
dischi. Le post
righe che non post_comment
sono associate sono escluse poiché non possono soddisfare la condizione della clausola ON.
Ancora una volta, la query SQL INNER JOIN sopra riportata equivale alla seguente query CROSS JOIN:
SELECT
p.id AS "p.id",
pc.post_id AS "pc.post_id",
pc.id AS "pc.id",
p.title AS "p.title",
pc.review AS "pc.review"
FROM post p, post_comment pc
WHERE pc.post_id = p.id
Le righe non colpite sono quelle che soddisfano la clausola WHERE e solo questi record verranno inclusi nel set di risultati. Questo è il modo migliore per visualizzare come funziona la clausola INNER JOIN.
| p.id | pc.post_id | pc.id | p.title | pc.review |
| ------ | ------------ | ------- | ----------- | --------- - |
| 1 | 1 | 1 | Java | Buono |
| 1 | 1 | 2 | Java | Eccellente |
| 1 | 2 | 3 | Java | Fantastico |
| 2 | 1 | 1 | Ibernazione | Buono |
| 2 | 1 | 2 | Ibernazione | Eccellente |
| 2 | 2 | 3 | Ibernazione | Fantastico |
| 3 | 1 | 1 | JPA | Buono |
| 3 | 1 | 2 | JPA | Eccellente |
| 3 | 2 | 3 | JPA | Fantastico |
Conclusione
Un'istruzione INNER JOIN può essere riscritta come CROSS JOIN con una clausola WHERE che corrisponde alla stessa condizione utilizzata nella clausola ON della query INNER JOIN.
Non che ciò si applichi solo a INNER JOIN, non a OUTER JOIN.