Да, използвам и трите от тези JOIN, въпреки че съм склонен да се придържам към използването само на LEFT (OUTER) JOIN
s вместо смесване на LEFT и RIGHT JOIN. Използвам също FULL OUTER JOIN
s и CROSS JOIN
с.
В обобщение, INNER JOIN
ограничава набора от резултати само до онези записи, удовлетворени от условието JOIN. Помислете за следните таблици
РЕДАКТИРАНЕ: Преименувах имената на таблиците и ги поставих с префикс @
така че променливите в таблицата да могат да се използват за всеки, който чете този отговор и желае да експериментира.
Ако искате също да експериментирате с това в браузъра, Настроих всичко това на SQL Fiddle също;
@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
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
SQL изявление, присъединено към id
поле
SELECT
t1.id,
t1.name,
t2.name
FROM
@Table1 t1
INNER JOIN
@Table2 t2
ON
t1.id = t2.id
Резултати в
id | name | name
----------------
1 | One | Partridge
2 | Two | Turtle Doves
3 | Three| French Hens
A LEFT JOIN
ще върне набор от резултати с всички записи от таблицата от лявата страна на съединението (ако трябва да изпишете израза като един ред, таблицата, която се появява първа) и полета от таблицата от дясната страна на съединението които съответстват на израза за присъединяване и са включени в SELECT
клауза. Липсва подробностите ще бъдат попълнени с NULL
SELECT
t1.id,
t1.name,
t2.name
FROM
@Table1 t1
LEFT JOIN
@Table2 t2
ON
t1.id = t2.id
Резултати в
id | name | name
----------------
1 | One | Partridge
2 | Two | Turtle Doves
3 | Three| French Hens
4 | Four | NULL
A RIGHT JOIN
е същата логика като LEFT JOIN
но ще върне всички записи от дясната страна на съединението и полета от лявата страна, които съответстват на израза за присъединяване и са включени в SELECT
клауза.
SELECT
t1.id,
t1.name,
t2.name
FROM
@Table1 t1
RIGHT JOIN
@Table2 t2
ON
t1.id = t2.id
Резултати в
id | name | name
----------------
1 | One | Partridge
2 | Two | Turtle Doves
3 | Three| French Hens
NULL| NULL| Gold Rings
Разбира се, има и FULL OUTER JOIN
, който включва записи от двете обединени таблици и попълва всички липсващи подробности с NULL.
SELECT
t1.id,
t1.name,
t2.name
FROM
@Table1 t1
FULL OUTER JOIN
@Table2 t2
ON
t1.id = t2.id
Резултати в
id | name | name
----------------
1 | One | Partridge
2 | Two | Turtle Doves
3 | Three| French Hens
4 | Four | NULL
NULL| NULL| Gold Rings
И CROSS JOIN
(известен също като CARTESIAN PRODUCT
), което е просто продукт на кръстосано прилагане на полета в SELECT
оператор от една таблица с полетата в SELECT
изявление от другата маса. Забележете, че в CROSS JOIN
няма израз за присъединяване
SELECT
t1.id,
t1.name,
t2.name
FROM
@Table1 t1
CROSS JOIN
@Table2 t2
Резултати в
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
РЕДАКТИРАНЕ:
Представете си, че сега има Table3
@Table3
id | name
---------
2 | Prime 1
3 | Prime 2
5 | Prime 3
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');
Сега и трите таблици са обединени с 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
Резултати в
id | name | name | name
-------------------------------
2 | Two | Turtle Doves | Prime 1
3 | Three| French Hens | Prime 2
Може да помогне да разберете този резултат, като си помислите, че записите с идентификатор 2 и 3 са единствените, общи за всичките 3 таблици и са също полето, към което се присъединяваме към всяка таблица.
Сега и трите с 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
Резултати в
id | name | name | name
-------------------------------
1 | One | Partridge | NULL
2 | Two | Turtle Doves | Prime 1
3 | Three| French Hens | Prime 2
4 | Four | NULL | NULL
Отговорът на Джоел е добро обяснение за обяснението на този набор от резултати (Таблица 1 е основната/произходната таблица).
Сега с INNER JOIN
и 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
Резултати в
id | name | name | name
-------------------------------
1 | One | Partridge | NULL
2 | Two | Turtle Doves | Prime 1
3 | Three| French Hens | Prime 2
Въпреки че не знаем реда, в който оптимизаторът на заявки ще изпълнява операциите, ще разгледаме тази заявка отгоре надолу, за да разберем набора от резултати. INNER JOIN
на идентификатори между Table1 и Table2 ще ограничи набора от резултати до само онези записи, удовлетворени от условието за присъединяване, т.е. трите реда, които видяхме в първия пример. Това временно резултатният набор ще бъде LEFT JOIN
ed до Table3 на идентификатори между Table1 и Tables; В Table3 има записи с id 2 и 3, но не и id 1, така че полето t3.name ще съдържа подробности за 2 и 3, но не и за 1.