SQL присоединяется как диаграмма Венна

У меня были проблемы с пониманием соединений в SQL и наткнулся на это изображение, которое я думаю, может помочь мне. Проблема в том, что я не до конца понимаю. Например, объединение в верхнем правом углу изображения, которое окрашивает весь кружок B в красный цвет и перекрывает только A. На изображении кажется, что кружок B является основным фокусом оператора SQL, но оператора SQL. само по себе, начиная с A (выберите из A, присоединитесь к B), создает для меня противоположное впечатление, а именно, что A будет в центре внимания оператора sql.

Аналогично, изображение ниже, которое включает в себя только данные из круга B, так почему A вообще включено в оператор соединения?

Вопрос: Работая по часовой стрелке сверху справа и заканчивая в центре, кто-нибудь может предоставить больше информации о представлении каждого изображения sql, объясняя

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

б) и любые другие детали, которые бы прояснили, почему изображение является хорошим представлением SQL

5 ответов

Решение

Я думаю, что ваша основная путаница заключается в том, что когда (например) только A выделено красным цветом, это означает, что "запрос возвращает данные только из A ", но на самом деле это означает" запрос возвращает данные только для тех случаев, когда A имеет запись ". Запрос может по-прежнему содержать данные из B. (Для случаев, когда B не имеет записи, запрос заменит NULL.)

Аналогично, изображение ниже, которое включает в себя только данные из круга B, так почему A вообще включено в оператор соединения?

Если вы имеете в виду - изображение где A полностью в белом, и есть красная форма полумесяца для части B это не совпадает с A тогда: причина того, что A появляется в запросе, A как он находит записи в B это должно быть исключено. (Если A не появилось в запросе, тогда диаграмма Венна не имела бы A было бы только показать B и не было бы никакого способа отличить нужные записи от ненужных.)

Изображение заставляет казаться, что круг B является основным фокусом оператора sql, но сам оператор sql, начиная с A (выберите из A, присоединиться к B), создает для меня противоположное впечатление, а именно, что A будет фокусом SQL заявление.

Совершенно верно. По этой причине, RIGHT JOIN с относительно редки; хотя запрос, который использует LEFT JOIN почти всегда можно изменить порядок использования RIGHT JOIN вместо этого (и наоборот) обычно люди пишут свои запросы с LEFT JOIN а не с RIGHT JOIN,

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

таблицы

таблицы

ВЫБРАТЬ A.Colour, B.Colour ОТ CROSS JOIN B SQL Fiddle

Перекрестное соединение (или декартово произведение) дает результат для каждой комбинации строк из двух таблиц. Каждая таблица имеет 4 строки, поэтому в результате получается 16 строк.

Перекрестное соединение

ВЫБРАТЬ A.Colour, B.Colour ИЗ ВНУТРЕННЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour SQL Fiddle

Внутреннее соединение логически возвращает все строки перекрестного соединения, которые соответствуют условию соединения. В этом случае пять сделать.

Внутреннее соединение

ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ВНУТРЕННЕГО СОЕДИНЕНИЯ B НА A.Colour NOT IN ("Зеленый", "Синий") SQL Fiddle

Условие внутреннего соединения не обязательно должно быть условием равенства и не должно ссылаться на столбцы обеих (или даже обеих) таблиц. Оценка A.Colour NOT IN ('Green','Blue') на каждом ряду перекрестного соединения возвращается.

внутренний 2

Состояние внутреннего соединения 1=1 будет иметь значение true для каждой строки в перекрестном соединении, поэтому эти два значения эквивалентны ( SQL Fiddle).

ВЫБРАТЬ A.Colour, B.Colour ИЗ ЛЕВОГО ВНЕШНЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour SQL Fiddle

Внешние объединения логически оцениваются так же, как и внутренние соединения, за исключением того, что если строка из левой таблицы (для левого объединения) вообще не объединяется ни с одной строкой из правой таблицы, она сохраняется в результате с NULL значения для правых столбцов.

LOJ

ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ЛЕВОГО ВНЕШНЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour ГДЕ B.Colour IS NULL SQL Fiddle

Это просто ограничивает предыдущий результат, возвращая только те строки, где B.Colour IS NULL, В этом конкретном случае это будут строки, которые были сохранены, так как они не совпадали в правой таблице, и запрос возвращает одну красную строку, не сопоставленную в таблице. B, Это известно как анти-полусоединение.

Важно выбрать столбец для IS NULL тест, который либо не обнуляется, либо для которого условие соединения гарантирует, что любой NULL значения будут исключены, чтобы этот шаблон работал правильно и избегал просто возвращать строки, которые имеют NULL значение для этого столбца в дополнение к несоответствующим строкам.

Ложа ноль

ВЫБРАТЬ A.Colour, B.Colour ИЗ ПРАВИЛЬНОГО ВНЕШНЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour SQL Fiddle

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

ROJ

ВЫБРАТЬ A.Colour, B.Colour ИЗ ПОЛНОГО НАРУЖНОГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour SQL Fiddle

Полные внешние объединения объединяют поведение левого и правого объединений и сохраняют несовпадающие строки из левой и правой таблиц.

FOJ

Диаграммы Венна подходят для представления операций над множествами, таких как UNION, INTERSECTS, EXCEPT и т. Д.

В той степени, в которой только те операции над множествами, как EXCEPT, имитируются с такими вещами, как LEFT JOIN WHERE rhs.KEY имеет значение NULL, эта диаграмма является точной.

В противном случае это вводит в заблуждение. Например, любое объединение может привести к умножению строк, если критерии объединения не 1:1. Но наборы могут содержать только отдельные элементы, поэтому они не могут быть представлены как операции над множествами.

Затем происходит CROSS JOIN или INNER JOIN ON 1 = 1 - это не аналогично INNER JOIN, как показано на этой диаграмме, и набор, который создается, не может быть действительно описан диаграммой Венна. Не говоря уже о всех других возможных треугольных соединениях, self и anti-joins, таких как:

lhs INNER JOIN rhs ON rhs.VALUE < lhs.VALUE (triangular)

или же

SELF self1
INNER JOIN SELF self2
    ON self2.key <> self1.key
    AND self1.type = self2.type

(self cross и anti-join найти всех похожих членов семьи, кроме вас - self1 и self2 - это одно и то же множество, и в результате получается правильное подмножество)

Придерживаться объединений на клавишах может быть хорошо в течение первых нескольких минут учебного курса, но это может привести к плохому пути для изучения того, что такое объединения. Я думаю, что это то, что вы нашли.

Идея, что диаграммы Венна могут представлять СОЕДИНЕНИЯ, как правило, должна исчезнуть.

Когда вы делаете соединение, вполне вероятно, что ваши две таблицы могут не совпадать идеально. В частности, в A могут быть строки, которые не совпадают ни с чем в B, или дубликаты строк в A, совпадающие с одной строкой в ​​B, и наоборот.

Когда это происходит, у вас есть выбор:

  1. для каждого A возьмите один B, который работает, если он есть. (верхний левый)
  2. возьмите каждую пару, которая полностью совпадает (откажитесь от любой пары, в которой отсутствует A или B- центр)
  3. для каждого B возьмите один A, который работает, если он есть (вверху справа)
  4. возьми ВСЕ (внизу слева)

Центр слева и справа технически соединены, но бессмысленны; они могли бы быть написаны более эффективно SELECT <select_list> FROM TableA A WHERE A.Key NOT IN (SELECT B.Key FROM TableB B) (или наоборот).

В прямой ответ на вашу путаницу, RIGHT JOIN говорит "следующее выражение является фокусом этого запроса". Справа внизу довольно странно, и я не вижу причин, почему вы хотели бы этого. Он возвращает результаты двух внешних средних запросов, смешанных вместе с NULLво всех столбцах для противоположной таблицы.

Для правильного объединения, да, синтаксис может сбивать с толку, но да, это то, что кажется. Когда вы говорите "TableA RIGHT JOIN TableB", это действительно говорит о том, что TableB - это основная таблица, на которую вы ссылаетесь, а TableA просто висит там, где есть соответствующие записи. Это выглядит странно в запросах, потому что TableA указан первым, поэтому ваш мозг автоматически назначает ему больший приоритет, хотя TableB действительно является более важной таблицей в запросе. По этой причине вы редко видите правильные объединения в реальном коде.

Итак, вместо A и B, давайте возьмем две вещи, которые легко отслеживать. Предположим, у нас есть две таблицы для информации о людях, ShoeSize и IQ. У вас есть информация об ShoeSize для некоторых людей, информация о IQ для некоторых людей. И есть PersonID на обеих таблицах, к которым вы можете присоединиться.

По часовой стрелке сверху справа (даже если это начинается с некоторых из более сложных и надуманных случаев):

  • ShoeSize RIGHT JOIN IQ -> дайте мне всю информацию о IQ. Включите любую информацию об обуви для этих людей, если она у нас есть.
  • ShoeSize RIGHT JOIN IQ WHERE ShowSize.PersonID = NULL -> Дайте мне всю информацию IQ, но только для людей, у которых нет информации о размере обуви
  • ShoeSize FULL OUTER JOIN IQ WHERE ShoeSize.PersonID = NULL AND IQ.PersonID = NULL -> Дайте мне информацию о размере обуви только для людей, у которых нет информации IQ, плюс информацию о IQ для людей, у которых нет информации о размере обуви
  • ShoeSize FULL OUTER JOIN IQ -> Дайте мне все, все размеры обуви и все данные IQ. Если какие-либо записи ShoeSizes и IQ имеют одинаковый PersonID, включите их в одну строку.
  • ShoeSize LEFT JOIN IQ WHERE IQ.PersonID = NULL -> Дайте мне всю информацию о размере обуви, но только для людей, у которых нет информации IQ
  • ShoeSize LEFT JOIN IQ -> Дайте мне всю информацию о размере обуви. Включите любую информацию IQ для этих людей, если она у нас есть.
Другие вопросы по тегам