Tak, używam wszystkich trzech JOIN, chociaż zwykle trzymam się tylko LEFT (OUTER) JOIN
zamiast mieszać lewe i prawe JOIN. Używam również FULL OUTER JOIN
s i CROSS JOIN
s.
Podsumowując, INNER JOIN
ogranicza zestaw wyników tylko do tych rekordów, które spełniają warunek JOIN. Rozważ następujące tabele
EDYTUJ: Zmieniłem nazwy tabel i poprzedziłem je @
aby zmienne tabeli mogły być używane przez każdego, kto czyta tę odpowiedź i chce poeksperymentować.
Jeśli chcesz poeksperymentować z tym w przeglądarce, ustawiłem to wszystko w SQL Fiddle też;
@Table1
id | name
---------
1 | One
2 | Two
3 | Three
4 | Four
@Table2
id | name
---------
1 | Partridge
2 | Turtle Doves
3 | French Hens
5 | Gold Rings
Kod SQL
DECLARE @Table1 TABLE (id INT PRIMARY KEY CLUSTERED, [name] VARCHAR(25))
INSERT INTO @Table1 VALUES(1, 'One');
INSERT INTO @Table1 VALUES(2, 'Two');
INSERT INTO @Table1 VALUES(3, 'Three');
INSERT INTO @Table1 VALUES(4, 'Four');
DECLARE @Table2 TABLE (id INT PRIMARY KEY CLUSTERED, [name] VARCHAR(25))
INSERT INTO @Table2 VALUES(1, 'Partridge');
INSERT INTO @Table2 VALUES(2, 'Turtle Doves');
INSERT INTO @Table2 VALUES(3, 'French Hens');
INSERT INTO @Table2 VALUES(5, 'Gold Rings');
INNER JOIN
Instrukcja SQL, dołączona do id
pole
SELECT
t1.id,
t1.name,
t2.name
FROM
@Table1 t1
INNER JOIN
@Table2 t2
ON
t1.id = t2.id
Wyniki w
id | name | name
----------------
1 | One | Partridge
2 | Two | Turtle Doves
3 | Three| French Hens
LEFT JOIN
zwróci zestaw wyników ze wszystkimi rekordami z tabeli po lewej stronie złączenia (jeżeli miałbyś napisać instrukcję jako jedną linijkę, tabela, która pojawia się jako pierwsza) oraz pola z tabeli po prawej stronie złączenia które pasują do wyrażenia sprzężenia i są zawarte w SELECT
klauzula. Brak szczegóły zostaną wypełnione NULL
SELECT
t1.id,
t1.name,
t2.name
FROM
@Table1 t1
LEFT JOIN
@Table2 t2
ON
t1.id = t2.id
Wyniki w
id | name | name
----------------
1 | One | Partridge
2 | Two | Turtle Doves
3 | Three| French Hens
4 | Four | NULL
RIGHT JOIN
jest taka sama jak logika LEFT JOIN
ale zwróci wszystkie rekordy z prawej strony złączenia i pola z lewej strony, które pasują do wyrażenia złączenia i są zawarte w SELECT
klauzula.
SELECT
t1.id,
t1.name,
t2.name
FROM
@Table1 t1
RIGHT JOIN
@Table2 t2
ON
t1.id = t2.id
Wyniki w
id | name | name
----------------
1 | One | Partridge
2 | Two | Turtle Doves
3 | Three| French Hens
NULL| NULL| Gold Rings
Oczywiście istnieje również FULL OUTER JOIN
, który zawiera rekordy z obu połączonych tabel i wypełnia wszystkie brakujące szczegóły z NULL.
SELECT
t1.id,
t1.name,
t2.name
FROM
@Table1 t1
FULL OUTER JOIN
@Table2 t2
ON
t1.id = t2.id
Wyniki w
id | name | name
----------------
1 | One | Partridge
2 | Two | Turtle Doves
3 | Three| French Hens
4 | Four | NULL
NULL| NULL| Gold Rings
Oraz CROSS JOIN
(znany również jako CARTESIAN PRODUCT
), który jest po prostu produktem krzyżowego stosowania pól w SELECT
oświadczenie z jednej tabeli z polami w SELECT
oświadczenie z drugiej tabeli. Zauważ, że nie ma wyrażenia złączenia w CROSS JOIN
SELECT
t1.id,
t1.name,
t2.name
FROM
@Table1 t1
CROSS JOIN
@Table2 t2
Wyniki w
id | name | name
------------------
1 | One | Partridge
2 | Two | Partridge
3 | Three | Partridge
4 | Four | Partridge
1 | One | Turtle Doves
2 | Two | Turtle Doves
3 | Three | Turtle Doves
4 | Four | Turtle Doves
1 | One | French Hens
2 | Two | French Hens
3 | Three | French Hens
4 | Four | French Hens
1 | One | Gold Rings
2 | Two | Gold Rings
3 | Three | Gold Rings
4 | Four | Gold Rings
EDYTUJ:
Wyobraź sobie, że jest teraz Tabela3
@Table3
id | name
---------
2 | Prime 1
3 | Prime 2
5 | Prime 3
Kod SQL
DECLARE @Table3 TABLE (id INT PRIMARY KEY CLUSTERED, [name] VARCHAR(25))
INSERT INTO @Table3 VALUES(2, 'Prime 1');
INSERT INTO @Table3 VALUES(3, 'Prime 2');
INSERT INTO @Table3 VALUES(5, 'Prime 3');
Teraz wszystkie trzy tabele połączone za pomocą INNER JOINS
SELECT
t1.id,
t1.name,
t2.name,
t3.name
FROM
@Table1 t1
INNER JOIN
@Table2 t2
ON
t1.id = t2.id
INNER JOIN
@Table3 t3
ON
t1.id = t3.id
Wyniki w
id | name | name | name
-------------------------------
2 | Two | Turtle Doves | Prime 1
3 | Three| French Hens | Prime 2
Zrozumienie tego wyniku może pomóc, myśląc, że rekordy o identyfikatorach 2 i 3 są jedynymi wspólnymi dla wszystkich 3 tabel i są również polem, na którym dołączamy do każdego stołu.
Teraz wszystkie trzy z LEFT JOINS
SELECT
t1.id,
t1.name,
t2.name,
t3.name
FROM
@Table1 t1
LEFT JOIN
@Table2 t2
ON
t1.id = t2.id
LEFT JOIN
@Table3 t3
ON
t1.id = t3.id
Wyniki w
id | name | name | name
-------------------------------
1 | One | Partridge | NULL
2 | Two | Turtle Doves | Prime 1
3 | Three| French Hens | Prime 2
4 | Four | NULL | NULL
Odpowiedź Joela jest dobrym wyjaśnieniem tego zestawu wyników (Tabela 1 jest tabelą bazową/początkową).
Teraz z INNER JOIN
i LEFT JOIN
SELECT
t1.id,
t1.name,
t2.name,
t3.name
FROM
@Table1 t1
INNER JOIN
@Table2 t2
ON
t1.id = t2.id
LEFT JOIN
@Table3 t3
ON
t1.id = t3.id
Wyniki w
id | name | name | name
-------------------------------
1 | One | Partridge | NULL
2 | Two | Turtle Doves | Prime 1
3 | Three| French Hens | Prime 2
Chociaż nie znamy kolejności, w jakiej optymalizator zapytań wykona operacje, przyjrzymy się temu zapytaniu od góry do dołu, aby zrozumieć zestaw wyników. INNER JOIN
on ids pomiędzy Table1 i Table2 ograniczy zestaw wyników tylko do tych rekordów, które spełniają warunek złączenia, tj. do trzech wierszy, które widzieliśmy w pierwszym przykładzie. Ten tymczasowy zestaw wyników będzie wtedy LEFT JOIN
ed do Tabeli 3 na identyfikatory między Tabelą 1 a Tabelami; W tabeli 3 znajdują się rekordy o identyfikatorach 2 i 3, ale nie o identyfikatorze 1, więc pole t3.name będzie zawierało szczegóły dla 2 i 3, ale nie 1.