Join (SQL)

Поделись знанием:
Перейти к: навигация, поиск

JOIN — оператор языка SQL, который является реализацией операции соединения реляционной алгебры. Входит в раздел FROM операторов SELECT, UPDATE или DELETE.

Операция соединения, как и другие бинарные операции, предназначена для обеспечения выборки данных из двух таблиц и включения этих данных в один результирующий набор. Отличительными особенностями операции соединения являются следующее:

  • в схему таблицы-результата входят столбцы обеих исходных таблиц (таблиц-операндов), то есть схема результата является «сцеплением» схем операндов;
  • каждая строка таблицы-результата является «сцеплением» строки из одной таблицы-операнда со строкой второй таблицы-операнда.

Определение того, какие именно исходные строки войдут в результат и в каких сочетаниях, зависит от типа операции соединения и от явно заданного условия соединения. Условие соединения, то есть условие сопоставления строк исходных таблиц друг с другом, представляет собой логическое выражение (предикат).

При необходимости соединения не двух, а нескольких таблиц, операция соединения применяется несколько раз (последовательно).





Описание оператора

SELECT
  field_name [,... n]
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 используется оператор «запятая» (,):

SELECT
  field_name [,... n]
FROM
  Table1,
  Table2

Виды оператора JOIN

Для дальнейших пояснений будут использоваться следующие таблицы:

City (Города)
Id Name
1 Москва
2 Санкт-Петербург
3 Казань
Person (Люди)
Name CityId
Андрей 1
Леонид 2
Сергей 1
Григорий 4

INNER JOIN

Оператор внутреннего соединения 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 Москва

OUTER JOIN

Соединение двух таблиц, в результат которого в обязательном порядке входят все строки либо одной, либо обеих таблиц.

LEFT OUTER JOIN

Оператор левого внешнего соединения LEFT OUTER JOIN соединяет две таблицы. Порядок таблиц для оператора важен, поскольку оператор не является симметричным.

Заголовок таблицы-результата является объединением (конкатенацией) заголовков соединяемых таблиц.

Тело результата логически формируется следующим образом. Пусть выполняется соединение левой и правой таблиц по предикату (условию) p.

  1. В результат включается внутреннее соединение (INNER JOIN) левой и правой таблиц по предикату p.
  2. Затем в результат добавляются те записи левой таблицы, которые не вошли во внутреннее соединение на шаге 1. Для таких записей поля, соответствующие правой таблице, заполняются значениями 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

Оператор правого внешнего соединения RIGHT OUTER JOIN соединяет две таблицы. Порядок таблиц для оператора важен, поскольку оператор не является симметричным.

Заголовок таблицы-результата является объединением (конкатенацией) заголовков соединяемых таблиц.

Тело результата логически формируется следующим образом. Пусть выполняется соединение левой и правой таблиц по предикату (условию) p.

  1. В результат включается внутреннее соединение (INNER JOIN) левой и правой таблиц по предикату p.
  2. Затем в результат добавляются те записи правой таблицы, которые не вошли во внутреннее соединение на шаге 1. Для таких записей поля, соответствующие левой таблице, заполняются значениями 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

Оператор полного внешнего соединения FULL OUTER JOIN соединяет две таблицы. Порядок таблиц для оператора неважен, поскольку оператор является симметричным.

Заголовок таблицы-результата является объединением (конкатенацией) заголовков соединяемых таблиц.

Тело результата логически формируется следующим образом. Пусть выполняется соединение первой и второй таблиц по предикату (условию) p. Слова «первой» и «второй» здесь не обозначают порядок в записи (который неважен), а используются лишь для различения таблиц.

  1. В результат включается внутреннее соединение (INNER JOIN) первой и второй таблиц по предикату p.
  2. В результат добавляются те записи первой таблицы, которые не вошли во внутреннее соединение на шаге 1. Для таких записей поля, соответствующие второй таблице, заполняются значениями NULL.
  3. В результат добавляются те записи второй таблицы, которые не вошли во внутреннее соединение на шаге 1. Для таких записей поля, соответствующие первой таблице, заполняются значениями 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

Оператор перекрёстного соединения, или декартова произведения 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 CROSS JOIN t2 WHERE p
и
t1 INNER JOIN t2 ON p
синтаксически являются альтернативными формами записи одной и той же логической операции внутреннего соединения по предикату p. Синтаксис CROSS JOIN + WHERE для операции соединения называют устаревшим, его не рекомендует стандарт SQL ANSI[1][2].

Напишите отзыв о статье "Join (SQL)"

Примечания

  1. [msdn.microsoft.com/ru-ru/library/dd172122.aspx SR0010: не используйте устаревший синтаксис]
  2. [www.databasejournal.com/features/mssql/article.php/1438001/ANSI-Joins.htm ANSI Joins]

Ссылки

  • [www.javenue.info/post/20 Описание видов Join в Oracle] (рус.)
  • [www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html Jeff Atwood, A Visual Explanation of SQL Joins] (англ.)

Отрывок, характеризующий Join (SQL)


Маленькому сыну князя Андрея было семь лет. Он едва умел читать, он ничего не знал. Он многое пережил после этого дня, приобретая знания, наблюдательность, опытность; но ежели бы он владел тогда всеми этими после приобретенными способностями, он не мог бы лучше, глубже понять все значение той сцены, которую он видел между отцом, княжной Марьей и Наташей, чем он ее понял теперь. Он все понял и, не плача, вышел из комнаты, молча подошел к Наташе, вышедшей за ним, застенчиво взглянул на нее задумчивыми прекрасными глазами; приподнятая румяная верхняя губа его дрогнула, он прислонился к ней головой и заплакал.
С этого дня он избегал Десаля, избегал ласкавшую его графиню и либо сидел один, либо робко подходил к княжне Марье и к Наташе, которую он, казалось, полюбил еще больше своей тетки, и тихо и застенчиво ласкался к ним.
Княжна Марья, выйдя от князя Андрея, поняла вполне все то, что сказало ей лицо Наташи. Она не говорила больше с Наташей о надежде на спасение его жизни. Она чередовалась с нею у его дивана и не плакала больше, но беспрестанно молилась, обращаясь душою к тому вечному, непостижимому, которого присутствие так ощутительно было теперь над умиравшим человеком.


Князь Андрей не только знал, что он умрет, но он чувствовал, что он умирает, что он уже умер наполовину. Он испытывал сознание отчужденности от всего земного и радостной и странной легкости бытия. Он, не торопясь и не тревожась, ожидал того, что предстояло ему. То грозное, вечное, неведомое и далекое, присутствие которого он не переставал ощущать в продолжение всей своей жизни, теперь для него было близкое и – по той странной легкости бытия, которую он испытывал, – почти понятное и ощущаемое.
Прежде он боялся конца. Он два раза испытал это страшное мучительное чувство страха смерти, конца, и теперь уже не понимал его.
Первый раз он испытал это чувство тогда, когда граната волчком вертелась перед ним и он смотрел на жнивье, на кусты, на небо и знал, что перед ним была смерть. Когда он очнулся после раны и в душе его, мгновенно, как бы освобожденный от удерживавшего его гнета жизни, распустился этот цветок любви, вечной, свободной, не зависящей от этой жизни, он уже не боялся смерти и не думал о ней.
Чем больше он, в те часы страдальческого уединения и полубреда, которые он провел после своей раны, вдумывался в новое, открытое ему начало вечной любви, тем более он, сам не чувствуя того, отрекался от земной жизни. Всё, всех любить, всегда жертвовать собой для любви, значило никого не любить, значило не жить этою земною жизнию. И чем больше он проникался этим началом любви, тем больше он отрекался от жизни и тем совершеннее уничтожал ту страшную преграду, которая без любви стоит между жизнью и смертью. Когда он, это первое время, вспоминал о том, что ему надо было умереть, он говорил себе: ну что ж, тем лучше.
Но после той ночи в Мытищах, когда в полубреду перед ним явилась та, которую он желал, и когда он, прижав к своим губам ее руку, заплакал тихими, радостными слезами, любовь к одной женщине незаметно закралась в его сердце и опять привязала его к жизни. И радостные и тревожные мысли стали приходить ему. Вспоминая ту минуту на перевязочном пункте, когда он увидал Курагина, он теперь не мог возвратиться к тому чувству: его мучил вопрос о том, жив ли он? И он не смел спросить этого.

Болезнь его шла своим физическим порядком, но то, что Наташа называла: это сделалось с ним, случилось с ним два дня перед приездом княжны Марьи. Это была та последняя нравственная борьба между жизнью и смертью, в которой смерть одержала победу. Это было неожиданное сознание того, что он еще дорожил жизнью, представлявшейся ему в любви к Наташе, и последний, покоренный припадок ужаса перед неведомым.
Это было вечером. Он был, как обыкновенно после обеда, в легком лихорадочном состоянии, и мысли его были чрезвычайно ясны. Соня сидела у стола. Он задремал. Вдруг ощущение счастья охватило его.
«А, это она вошла!» – подумал он.
Действительно, на месте Сони сидела только что неслышными шагами вошедшая Наташа.
С тех пор как она стала ходить за ним, он всегда испытывал это физическое ощущение ее близости. Она сидела на кресле, боком к нему, заслоняя собой от него свет свечи, и вязала чулок. (Она выучилась вязать чулки с тех пор, как раз князь Андрей сказал ей, что никто так не умеет ходить за больными, как старые няни, которые вяжут чулки, и что в вязании чулка есть что то успокоительное.) Тонкие пальцы ее быстро перебирали изредка сталкивающиеся спицы, и задумчивый профиль ее опущенного лица был ясно виден ему. Она сделала движенье – клубок скатился с ее колен. Она вздрогнула, оглянулась на него и, заслоняя свечу рукой, осторожным, гибким и точным движением изогнулась, подняла клубок и села в прежнее положение.
Он смотрел на нее, не шевелясь, и видел, что ей нужно было после своего движения вздохнуть во всю грудь, но она не решалась этого сделать и осторожно переводила дыханье.
В Троицкой лавре они говорили о прошедшем, и он сказал ей, что, ежели бы он был жив, он бы благодарил вечно бога за свою рану, которая свела его опять с нею; но с тех пор они никогда не говорили о будущем.
«Могло или не могло это быть? – думал он теперь, глядя на нее и прислушиваясь к легкому стальному звуку спиц. – Неужели только затем так странно свела меня с нею судьба, чтобы мне умереть?.. Неужели мне открылась истина жизни только для того, чтобы я жил во лжи? Я люблю ее больше всего в мире. Но что же делать мне, ежели я люблю ее?» – сказал он, и он вдруг невольно застонал, по привычке, которую он приобрел во время своих страданий.
Услыхав этот звук, Наташа положила чулок, перегнулась ближе к нему и вдруг, заметив его светящиеся глаза, подошла к нему легким шагом и нагнулась.
– Вы не спите?
– Нет, я давно смотрю на вас; я почувствовал, когда вы вошли. Никто, как вы, но дает мне той мягкой тишины… того света. Мне так и хочется плакать от радости.
Наташа ближе придвинулась к нему. Лицо ее сияло восторженною радостью.
– Наташа, я слишком люблю вас. Больше всего на свете.
– А я? – Она отвернулась на мгновение. – Отчего же слишком? – сказала она.
– Отчего слишком?.. Ну, как вы думаете, как вы чувствуете по душе, по всей душе, буду я жив? Как вам кажется?
– Я уверена, я уверена! – почти вскрикнула Наташа, страстным движением взяв его за обе руки.
Он помолчал.
– Как бы хорошо! – И, взяв ее руку, он поцеловал ее.
Наташа была счастлива и взволнована; и тотчас же она вспомнила, что этого нельзя, что ему нужно спокойствие.
– Однако вы не спали, – сказала она, подавляя свою радость. – Постарайтесь заснуть… пожалуйста.
Он выпустил, пожав ее, ее руку, она перешла к свече и опять села в прежнее положение. Два раза она оглянулась на него, глаза его светились ей навстречу. Она задала себе урок на чулке и сказала себе, что до тех пор она не оглянется, пока не кончит его.
Действительно, скоро после этого он закрыл глаза и заснул. Он спал недолго и вдруг в холодном поту тревожно проснулся.
Засыпая, он думал все о том же, о чем он думал все ото время, – о жизни и смерти. И больше о смерти. Он чувствовал себя ближе к ней.
«Любовь? Что такое любовь? – думал он. – Любовь мешает смерти. Любовь есть жизнь. Все, все, что я понимаю, я понимаю только потому, что люблю. Все есть, все существует только потому, что я люблю. Все связано одною ею. Любовь есть бог, и умереть – значит мне, частице любви, вернуться к общему и вечному источнику». Мысли эти показались ему утешительны. Но это были только мысли. Чего то недоставало в них, что то было односторонне личное, умственное – не было очевидности. И было то же беспокойство и неясность. Он заснул.
Он видел во сне, что он лежит в той же комнате, в которой он лежал в действительности, но что он не ранен, а здоров. Много разных лиц, ничтожных, равнодушных, являются перед князем Андреем. Он говорит с ними, спорит о чем то ненужном. Они сбираются ехать куда то. Князь Андрей смутно припоминает, что все это ничтожно и что у него есть другие, важнейшие заботы, но продолжает говорить, удивляя их, какие то пустые, остроумные слова. Понемногу, незаметно все эти лица начинают исчезать, и все заменяется одним вопросом о затворенной двери. Он встает и идет к двери, чтобы задвинуть задвижку и запереть ее. Оттого, что он успеет или не успеет запереть ее, зависит все. Он идет, спешит, ноги его не двигаются, и он знает, что не успеет запереть дверь, но все таки болезненно напрягает все свои силы. И мучительный страх охватывает его. И этот страх есть страх смерти: за дверью стоит оно. Но в то же время как он бессильно неловко подползает к двери, это что то ужасное, с другой стороны уже, надавливая, ломится в нее. Что то не человеческое – смерть – ломится в дверь, и надо удержать ее. Он ухватывается за дверь, напрягает последние усилия – запереть уже нельзя – хоть удержать ее; но силы его слабы, неловки, и, надавливаемая ужасным, дверь отворяется и опять затворяется.