To bardzo częste pytanie, więc ta odpowiedź jest oparta na tym artykule, który napisałem.
Relacja tabeli
Biorąc pod uwagę, że mamy następujące post
i post_comment
tabele:
post
Ma następujące zapisy:
| id | title |
|----|-----------|
| 1 | Java |
| 2 | Hibernate |
| 3 | JPA |
i post_comment
ma następujące trzy rzędy:
| id | review | post_id |
|----|-----------|---------|
| 1 | Good | 1 |
| 2 | Excellent | 1 |
| 3 | Awesome | 2 |
DOŁĄCZ DO WEWNĘTRZNEGO SQL
Klauzula JOIN SQL umożliwia powiązanie wierszy należących do różnych tabel. Na przykład CROSS JOIN utworzy produkt kartezjański zawierający wszystkie możliwe kombinacje wierszy między dwiema tabelami łączenia.
Chociaż połączenie krzyżowe jest przydatne w niektórych scenariuszach, w większości przypadków chcesz łączyć tabele w oparciu o określony warunek. I tu właśnie wchodzi INNER JOIN.
SQL INNER JOIN pozwala nam filtrować produkt kartezjański łączenia dwóch tabel w oparciu o warunek określony za pomocą klauzuli ON.
DOŁĄCZ DO WEWNĘTRZNEGO SQL - W stanie „zawsze prawdziwa”
Jeśli podasz warunek „zawsze prawda”, ŁĄCZENIE WEWNĘTRZNE nie będzie filtrowało połączonych rekordów, a zestaw wyników będzie zawierał iloczyn kartezjański dwóch tabel łączących.
Na przykład, jeśli wykonamy następujące zapytanie 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
Otrzymamy wszystkie kombinacje post
i post_comment
rekordy:
| p.id | pc.id |
|---------|------------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
Jeśli więc warunek klauzuli ON jest „zawsze prawdziwy”, INNER JOIN jest po prostu równoważne zapytaniu 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
DOŁĄCZ DO WEWNĘTRZNEGO SQL - W stanie „zawsze fałszywe”
Z drugiej strony, jeśli warunek klauzuli ON jest „zawsze fałszywy”, wówczas wszystkie połączone rekordy zostaną odfiltrowane, a zestaw wyników będzie pusty.
Jeśli więc wykonamy następujące zapytanie 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
Nie otrzymamy żadnego wyniku z powrotem:
| p.id | pc.id |
|---------|------------|
Dzieje się tak, ponieważ powyższe zapytanie jest równoważne następującemu zapytaniu 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 - ON klauzula przy użyciu kolumn klucza obcego i klucza podstawowego
Najczęstszym warunkiem klauzuli ON jest ten, który pasuje do kolumny Klucz obcy w tabeli podrzędnej z kolumną Klucz główny w tabeli nadrzędnej, co ilustruje następujące zapytanie:
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
Podczas wykonywania powyższego zapytania SQL INNER JOIN otrzymujemy następujący zestaw wyników:
| 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 |
Tak więc tylko rekordy spełniające warunek klauzuli ON są zawarte w zestawie wyników zapytania. W naszym przypadku zestaw wyników zawiera wszystkie dane post
wraz z ich post_comment
rekordami. Te post
wiersze, które nie związane post_comment
są wyłączone, ponieważ nie może spełniać warunek ON klauzuli.
Ponownie powyższe zapytanie SQL INNER JOIN jest równoważne następującemu zapytaniu 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
Nieprzestrzegane wiersze są tymi, które spełniają klauzulę WHERE i tylko te rekordy zostaną uwzględnione w zestawie wyników. To najlepszy sposób na wizualizację działania klauzuli INNER JOIN.
| p.id | pc.post_id | pc.id | p.title | przegląd pc. |
| ------ | ------------ | ------- | ----------- | --------- - |
| 1 | 1 | 1 | Java | Dobrze |
| 1 | 1 | 2 | Java | Doskonałe |
| 1 | 2 | 3 | Java | Niesamowite |
| 2 | 1 | 1 | Hibernacja | Dobrze |
| 2 | 1 | 2 | Hibernacja | Doskonałe |
| 2 | 2 | 3 | Hibernacja | Niesamowite |
| 3 | 1 | 1 | JPA | Dobrze |
| 3 | 1 | 2 | JPA | Doskonałe |
| 3 | 2 | 3 | JPA | Niesamowite |
Wniosek
Instrukcja INNER JOIN może zostać przepisana jako CROSS JOIN z klauzulą WHERE pasującą do tego samego warunku, którego użyto w klauzuli ON zapytania INNER JOIN.
Nie dotyczy to tylko DOŁĄCZENIA WEWNĘTRZNEGO, a nie DOŁĄCZANIA ZEWNĘTRZNEGO.