Microsoft SQL Server
- 1 year ago
- 0
- 0
JOIN — оператор языка SQL , который является реализацией операции соединения реляционной алгебры . Входит в предложение FROM операторов SELECT , UPDATE и DELETE .
Операция соединения, как и другие бинарные операции , предназначена для обеспечения выборки данных из двух таблиц и включения этих данных в один результирующий набор. Отличительными особенностями операции соединения являются следующие:
Определение того, какие именно исходные строки войдут в результат и в каких сочетаниях, зависит от типа операции соединения и от явно заданного условия соединения . Условие соединения, то есть условие сопоставления строк исходных таблиц друг с другом, представляет собой логическое выражение ( предикат ).
При необходимости соединения не двух, а нескольких таблиц, операция соединения применяется несколько раз (последовательно).
SQL-операция JOIN является реализацией операции соединения реляционной алгебры только в некотором приближении, поскольку в реляционной модели данных соединение выполняется над отношениями, которые являются множествами , а в SQL — над таблицами, которые являются мультимножествами . Результаты операций тоже, в общем случае, различны: в реляционной алгебре результат соединения даёт отношение (множество), а в SQL — таблицу (мультимножество).
FROM
Table1
{INNER | {LEFT | RIGHT | FULL} OUTER | CROSS } JOIN
Table2
{ON <condition> | USING (field_name [,... n])}
В большинстве СУБД при указании слов
LEFT
,
RIGHT
,
FULL
слово
OUTER
можно опустить.
Слово
INNER
также в большинстве СУБД можно опустить.
В общем случае СУБД при выполнении соединения проверяет условие (
предикат
)
condition
. Если названия столбцов, по которым происходит соединение таблиц, совпадают, то вместо
ON
можно использовать
USING
. Для
CROSS JOIN
условие не указывается.
Для перекрёстного соединения (декартова произведения)
CROSS JOIN
в некоторых реализациях SQL используется оператор «запятая» (
,
):
FROM
Table1,
Table2
Для дальнейших пояснений будут использоваться следующие таблицы:
Id | Name |
---|---|
1 | Москва |
2 | Санкт-Петербург |
3 | Казань |
Name | CityId |
---|---|
Андрей | 1 |
Леонид | 2 |
Сергей | 1 |
Григорий | 4 |
Оператор
внутреннего соединения
INNER JOIN
соединяет две таблицы. Порядок таблиц для оператора неважен, поскольку оператор является
коммутативным
.
Заголовок таблицы-результата является объединением ( конкатенацией ) заголовков соединяемых таблиц.
Тело результата логически формируется следующим образом. Каждая строка одной таблицы сопоставляется с каждой строкой второй таблицы, после чего для полученной «соединённой» строки проверяется условие соединения (вычисляется предикат соединения). Если условие истинно, в таблицу-результат добавляется соответствующая «соединённая» строка.
Описанный алгоритм действий является строго логическим, то есть он лишь объясняет результат, который должен получиться при выполнении операции, но не предписывает, чтобы конкретная СУБД выполняла соединение именно указанным образом. Существует несколько способов реализации операции соединения, например, соединение вложенными циклами ( англ. inner loops join ), соединение хешированием ( англ. hash join ), соединение слиянием ( англ. merge join ). Единственное требование состоит в том, чтобы любая реализация логически давала такой же результат, как при применении описанного алгоритма.
SELECT *
FROM
Person
INNER JOIN
City
ON Person.CityId = City.Id
Результат:
Person.Name | Person.CityId | City.Id | City.Name |
---|---|---|---|
Андрей | 1 | 1 | Москва |
Леонид | 2 | 2 | Санкт-Петербург |
Сергей | 1 | 1 | Москва |
Соединение двух таблиц, в результат которого обязательно входят все строки либо одной, либо обеих таблиц.
Оператор
левого внешнего соединения
LEFT OUTER JOIN
соединяет две таблицы. Порядок таблиц для оператора важен, поскольку оператор не является
коммутативным
.
Заголовок таблицы-результата является объединением ( конкатенацией ) заголовков соединяемых таблиц.
Тело результата логически формируется следующим образом. Пусть выполняется соединение левой и правой таблиц по предикату (условию) p .
INNER JOIN
) левой и правой таблиц по предикату
p
.
NULL
.
SELECT *
FROM
Person -- Левая таблица
LEFT OUTER JOIN
City -- Правая таблица
ON Person.CityId = City.Id
Результат:
Person.Name | Person.CityId | City.Id | City.Name |
---|---|---|---|
Андрей | 1 | 1 | Москва |
Леонид | 2 | 2 | Санкт-Петербург |
Сергей | 1 | 1 | Москва |
Григорий | 4 | NULL | NULL |
Оператор
правого внешнего соединения
RIGHT OUTER JOIN
соединяет две таблицы. Порядок таблиц для оператора важен, поскольку оператор не является
коммутативным
.
Заголовок таблицы-результата является объединением ( конкатенацией ) заголовков соединяемых таблиц.
Тело результата логически формируется следующим образом. Пусть выполняется соединение левой и правой таблиц по предикату (условию) p .
INNER JOIN
) левой и правой таблиц по предикату
p
.
NULL
.
SELECT *
FROM
Person -- Левая таблица
RIGHT OUTER JOIN
City -- Правая таблица
ON Person.CityId = City.Id
Результат:
Person.Name | Person.CityId | City.Id | City.Name |
---|---|---|---|
Андрей | 1 | 1 | Москва |
Сергей | 1 | 1 | Москва |
Леонид | 2 | 2 | Санкт-Петербург |
NULL | NULL | 3 | Казань |
Оператор
полного внешнего соединения
FULL OUTER JOIN
соединяет две таблицы. Порядок таблиц для оператора неважен, поскольку оператор является
коммутативным
.
Заголовок таблицы-результата является объединением ( конкатенацией ) заголовков соединяемых таблиц.
Тело результата логически формируется следующим образом. Пусть выполняется соединение первой и второй таблиц по предикату (условию) p . Слова «первой» и «второй» здесь не обозначают порядок в записи выражения (который неважен), а используются лишь для различения таблиц.
INNER JOIN
) первой и второй таблиц по предикату
p
.
NULL
.
NULL
.
SELECT *
FROM
Person
FULL OUTER JOIN
City
ON Person.CityId = City.Id
Результат:
Person.Name | Person.CityId | City.Id | City.Name |
---|---|---|---|
Андрей | 1 | 1 | Москва |
Сергей | 1 | 1 | Москва |
Леонид | 2 | 2 | Санкт-Петербург |
NULL | NULL | 3 | Казань |
Григорий | 4 | NULL | NULL |
Оператор
перекрёстного соединения
, или
декартова произведения
CROSS JOIN
соединяет две таблицы. Порядок таблиц для оператора неважен, поскольку оператор является
коммутативным
.
Заголовок таблицы-результата является объединением ( конкатенацией ) заголовков соединяемых таблиц.
Тело результата логически формируется следующим образом. Каждая строка одной таблицы соединяется с каждой строкой второй таблицы, давая тем самым в результате все возможные сочетания строк двух таблиц.
SELECT *
FROM
Person
CROSS JOIN
City
или
SELECT *
FROM
Person,
City
Результат:
Person.Name | Person.CityId | City.Id | City.Name |
---|---|---|---|
Андрей | 1 | 1 | Москва |
Андрей | 1 | 2 | Санкт-Петербург |
Андрей | 1 | 3 | Казань |
Леонид | 2 | 1 | Москва |
Леонид | 2 | 2 | Санкт-Петербург |
Леонид | 2 | 3 | Казань |
Сергей | 1 | 1 | Москва |
Сергей | 1 | 2 | Санкт-Петербург |
Сергей | 1 | 3 | Казань |
Григорий | 4 | 1 | Москва |
Григорий | 4 | 2 | Санкт-Петербург |
Григорий | 4 | 3 | Казань |
Если в предложении
WHERE
добавить условие соединения (предикат
p
), то есть ограничения на сочетания кортежей, то результат эквивалентен операции
INNER JOIN
с таким же условием:
SELECT *
FROM
Person,
City
WHERE
Person.CityId = City.Id
Таким образом, выражения
t1, t2 WHERE p
и
t1 INNER JOIN t2 ON p
синтаксически являются альтернативными формами записи одной и той же логической операции внутреннего соединения по предикату
p
. Синтаксис
CROSS JOIN + WHERE
для операции соединения называют устаревшим, его не рекомендует стандарт SQL ANSI
.