Визуальное пояснение JOIN'ов на SQL
11 декабря 2008 :: 39 комментариев :: 40327 просмотров :: 740 слов

Я думаю пост Ligaya Turmelle's про JOIN'ы в SQL - отличный пример для начинающих разработчиков. Поскольку SQL JOIN'ы очень хорошо видны на диаграммах Венна, покажем это. Но, как стало видно из комментариев к тому посту, диаграммы Венна не всегда полностью отображают всю суть JOIN'ов в реальных задачах.

Мне нравится концепция, поэтому давайте посмотрим, сможем ли мы заставить ее работать. Предположим, мы имеем следующие две таблицы. Таблица А находится слева, и таблица В справа. Мы будем заполнять их четырьмя записями каждую.

id name       id  name
-- ----       --  ----
1  Pirate     1   Rutabaga
2  Monkey     2   Pirate
3  Ninja      3   Darth Vader
4  Spaghetti  4   Ninja

Давайте соединять их разными способами и смотреть что же у нас получится на диаграммах Венна.

SELECT * FROM TableA
INNER JOIN TableB
ON TableA.name = TableB.name

id  name       id   name
--  ----       --   ----
1   Pirate     2    Pirate
3   Ninja      4    Ninja

Inner join выдает только те поля, которые есть как в таблице А так и в таблице В.

SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name

id    name       id    name
--    ----       --    ----
1     Pirate     2     Pirate
2     Monkey     null  null
3     Ninja      4     Ninja
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader

Full outer join производит набор всех записей в таблице А и в таблице В с возможностью совпадений записей в левой и правой таблицах. Если таковых нет, на пустой стороне вставляется NULL.

SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name

id  name       id    name
--  ----       --    ----
1   Pirate     2     Pirate
2   Monkey     null  null
3   Ninja      4     Ninja
4   Spaghetti  null  null

Left outer join производит набор всех полей в таблице А и в соответствии с ними набирает аналогичные в таблице В. Если соответствий в таблице В не найдено, вставляется NULL.

SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableB.id IS null

id  name       id     name
--  ----       --     ----
2   Monkey     null   null
4   Spaghetti  null   null

Выборка, обратная предыдущей. Находятся записи таблицы В, совпадающие с записами в А и тут же оба удаляются из выдачи. Выдаются те поля таблицы А, которых нет в таблице В.

SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableA.id IS null
OR TableB.id IS null

id    name       id    name
--    ----       --    ----
2     Monkey     null  null
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader
Тоже удаляет совпадающие записи, но теперь включает в выдачу еще и записи таблицы В, которых нет в таблице А. Есть еще один JOIN, который не может быть выражен так же на диаграмме Венна.
SELECT * FROM TableA
CROSS JOIN TableB

Этот JOIN означает "все к всему" ("everything to everything"), выдающий 4 х 4 = 16 строк, что намного больше, чем было в начале. Если вы сильны в математике, вы помете, что не стоит так запрашивать большие таблицы.

Это мой перевод статьи. Оригинал здесь.

Комментарии ↓
Elastep :: 11 июня 2009 в 10:39 из Odesa, UA #
1

Спасибо! Очень полезно!

x-dust :: 16 ноября 2009 в 08:12 из Saint Petersburg, RU #
1

Thanks!!!!

Владимир :: 19 ноября 2009 в 15:03 из Riga, LV #
1

Обалдено! Все никак не мог врубиться как работает JOIN. Огромное спасибо!

GreatCornholio :: 19 ноября 2009 в 17:34 #
1

Видимо, запись попала в топ какого-нибудь поиска по блогам.

Кстати, у меня одного вторая иллюстрация заехала на текст?

ReDetection :: 20 ноября 2009 в 16:15 из Novosibirsk, RU #
1

наверно. все нормально как с иллюстрациями, так и с текстом..

Саня :: 16 марта 2010 в 06:46 из Moscow, RU #
1

классно))) автору спасибо:)) теперь все стало понятно:)

J :: 24 апреля 2010 в 20:35 из UA #
1

Отлично, спасибо))

DAS :: 02 июня 2010 в 09:43 из KZ #
1

ВСЕ ЧЕТКО, КОРОТКО И ЯСНО ВСЕМ СПАСИБО!

Rave :: 02 июня 2010 в 14:59 из Sochi, RU #
1

иллюстрации значительно облегчают понимание. СПАСИБО!

rom :: 03 июня 2010 в 07:40 из Kiev, UA #
1

Дуууже дякую!!! Візуалізація - це те що треба для пояснення таких штук. Просто неймовірно ясно!!!

Bin :: 03 июня 2010 в 14:26 из Luk'yanovka, RU #
1

хохлi

Cornholio :: 04 июня 2010 в 12:12 из Novosibirsk, RU #
1

rom, Эм... а ты мог бы писать более ясно?

ReDetection :: 04 июня 2010 в 16:44 из Novosibirsk, RU #
1

Cornholio, имхо, тут и так все ясно. проверил гугл, он адекватно перевел.

vas3k :: 04 июня 2010 в 17:12 из Novosibirsk, RU #
1

Cornholio, а чого не зрозуміло тобі у рідній мові? Маскаль чтоль?

ReDetection :: 05 июня 2010 в 13:34 из Novosibirsk, RU #
1

V@s3K, чому раптом у рідному?

ReDetection :: 08 сентября 2010 в 05:27 из RU #
1

все разъехалось :(

BioK :: 08 октября 2010 в 15:25 из Posadas, AR #
1

Very usefull and clear(exept for the russian stuff) ha Just kiding. Regards from SouthAmerica.

Cornholio :: 09 октября 2010 в 07:56 из Novosibirsk, RU #
1

BioK, so the last line is definetly for you.

*definitely

JasonX :: 09 октября 2010 в 09:27 из Novosibirsk, RU #
1

слив засчитан.

ReDetection :: 09 октября 2010 в 16:29 из Novosibirsk, RU #
1

юсфул с одной л, а киддин - с двумя д. подозрительный тип.

vas3k :: 09 октября 2010 в 16:36 из Novosibirsk, RU #
1

ReDetection, никто так плохо не говорит на языке, как его носители (с) Вдумайся :D

themylogin :: 09 октября 2010 в 17:49 #
1

Пацаны, это аргентинский айпишник :-\

vas3k :: 09 октября 2010 в 17:53 из Novosibirsk, RU #
1

themylogin, ага, значит испанский.

Cornholio :: 11 октября 2010 в 13:34 из Novosibirsk, RU #
1

themylogin, Да и SouthAmerica, какбы намекает =)

ReDetection :: 16 октября 2010 в 09:45 из RU #
1

прямо сейчас понадобился cross join :) ну, во второй таблице запись всего одна и она зависит на условия вывода нескольких из первой. причем та одна запись довольно абстрактна, по-другому не приджойнишь :)

Дмитрий :: 30 ноября 2010 в 15:55 из Dnipro, UA #
1

Спасибо побольше бы таких объяснений.

Bin :: 30 ноября 2010 в 18:30 из Luk'yanovka, RU #
1

пожалуйста

ReDetection :: 03 апреля 2012 в 13:18 из Novosibirsk, RU #
1

опять все поехало D: Вася, я даю эту страничку вопрошающим, да и из поиска поди часто приходят. почини, пожалуйста!

vas3k :: 03 апреля 2012 в 14:28 из Novosibirsk, RU #
1

ReDetection, так лучше?

ReDetection :: 03 апреля 2012 в 15:29 из Novosibirsk, RU #
1

V@s3K, да, спасибо.

Денис :: 10 июня 2012 в 14:44 из Donetsk, UA #
1

Действительно очень доходчиво и понятно! Спасибо!

nkl :: 18 декабря 2012 в 19:26 из Karagandy, KZ #
0

Спасибо. Хорошие иллюстрации. Из какой книги вырезал?

vas3k :: 19 декабря 2012 в 04:05 из Novosibirsk, RU #
1

nkl, взял из оригинальной статьи, а автор мои и сам нарисовать

С В :: 09 июня 2013 в 14:20 из Kiev, UA #
1

Кто-нибуть написал бы книгу по SQL таким образом! Никак не мог врубиться, как же работает этот JOIN, и тут доступное объяснение, для новичков. С первого раза все понял. СПС огромное!

gardener :: 31 июля 2013 в 18:40 из Odesa, UA #
1

Все гениальное просто! МОЛОДЦА!

Федот :: 28 октября 2013 в 09:44 из RU #
1

Прекрасно, спасибо, очень просто и понятно объяснено.

Макс :: 30 января 2014 в 09:44 из Kiev, UA #
1

Спасибо отличная статья

Комментирование доступно только участникам Клуба

Войти
Еще? Тогда вот