Sql объединяется как диаграмма Венна

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

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

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

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

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

enter image description here

Ответ 1

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

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

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

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

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

Ответ 2

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

Таблицы

Tables

SELECT A.Colour, B.Colour FROM A CROSS JOIN B SQL Fiddle

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

Cross Join

SELECT A.Colour, B.Colour FROM IN INER JOIN B ON A.Colour = B.Colour SQL Fiddle

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

Inner Join

SELECT A.Colour, B.Colour FROM IN INER JOIN B ON A.Colour NOT IN ( "Зеленый", "Синий" ) SQL Fiddle

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

inner 2

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

SELECT A.Colour, B.Colour FROM A LEFT OUTER JOIN B ON A.Colour = B.Colour SQL Fiddle

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

LOJ

SELECT A.Colour, B.Colour FROM A LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour IS NULL SQL Fiddle

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

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

loj is null

SELECT A.Colour, B.Colour FROM A RIGHT OUTER JOIN B ON A.Colour = B.Colour SQL Fiddle

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

ROJ

SELECT A.Colour, B.Colour FROM FULL OUTER JOIN B ON A.Colour = B.Colour SQL Fiddle

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

FOJ

Ответ 3

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

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

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

Тогда есть КРОСС-ПРИСОЕДИНЕНИЕ или ВХОДНОЕ СОЕДИНЕНИЕ 1 = 1 - это не похоже на INNER JOIN, как показано на этой диаграмме, и не может быть создан набор, который будет действительно описан диаграммой Венна. Не говоря уже обо всех других возможных треугольных объединениях, я и анти-объединениях:

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 and anti-join, чтобы найти все похожие члены семейства, кроме себя - self1 и self2, являются одним и тем же множеством, а результат - правильным подмножеством)

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

Эта идея, которую Venn Diagrams может представлять JOINs, как правило, должна уйти.

Ответ 4

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

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

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

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

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

Ответ 5

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

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

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

  • ShoeSize RIGHT JOIN IQ → предоставить мне всю информацию IQ. Включите любую информацию ShoeSize для тех людей, если у нас есть.
  • 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 для тех людей, если у нас есть.