Предисловие

Я довольно визуальный человек. Вещи кажутся более понятными в картинках. Я искал в Интернете хорошее графическое представление SQL JOIN, но не нашел ни одного подходящего. У некоторых были хорошие диаграммы, но не хватало полноты (у них не было всех возможных СОЕДИНЕНИЙ), а некоторые были просто ужасны. Итак, я решил создать свой и написать об этом статью.

Напишем код

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

  1. INNER JOIN

  2. LEFT JOIN

  3. RIGHT JOIN

  4. OUTER JOIN

  5. LEFT JOIN EXCLUDING INNER JOIN

  6. RIGHT JOIN EXCLUDING INNER JOIN

  7. OUTER JOIN EXCLUDING INNER JOIN

В целях этой статьи я буду называть 5, 6 и 7 как LEFT EXCLUDING JOIN, RIGHT EXCLUDING JOIN и OUTER EXCLUDING JOIN соответственно. Некоторые могут возразить, что 5, 6 и 7 на самом деле не объединяют две таблицы, но для простоты я все равно буду называть их объединениями, потому что вы используете SQL-соединение в каждом из этих запросов (но исключите некоторые записи с предложением WHERE ).

Inner JOIN

Это простейший, наиболее понятный и самый распространенный способ объединения. Этот запрос вернет все записи в левой таблице (таблица A), у которых есть соответствующая запись в правой таблице (таблица B). Это соединение записывается следующим образом:

SELECT <select_list> 
FROM Table_A A
INNER JOIN Table_B B
ON A.Key = B.Key

Left JOIN

Этот запрос вернет все записи в левой таблице (таблица A) независимо от того, совпадают ли какие-либо из этих записей в правой таблице (таблица B). Он также вернет любые совпадающие записи из правой таблицы.

Это соединение записывается следующим образом:

SELECT <select_list>
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key

Right JOIN

Этот запрос вернет все записи в правой таблице (таблица B) независимо от того, совпадают ли какие-либо из этих записей в левой таблице (таблица A). Он также вернет любые совпадающие записи из левой таблицы. Это соединение записывается следующим образом:

SELECT <select_list>
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key

Outer Join

Это соединение также может называться ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ или ПОЛНОЕ СОЕДИНЕНИЕ. Этот запрос вернет все записи из обеих таблиц, объединяя записи из левой таблицы (таблица A), которые соответствуют записям из правой таблицы (таблица B). Это соединение записывается следующим образом:

SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key

Left Excluding JOIN

Этот запрос вернет все записи в левой таблице (таблица A), которые не соответствуют никаким записям в правой таблице (таблица B). Это соединение записывается следующим образом:

SELECT <select_list> 
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
WHERE B.Key IS NULL

Right Excluding JOIN

Этот запрос вернет все записи в правой таблице (таблица B), которые не соответствуют никаким записям в левой таблице (таблица A). Это соединение записывается следующим образом:

SELECT <select_list>
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL

Outer Excluding JOIN

Этот запрос вернет все записи в левой таблице (таблица A) и все записи в правой таблице (таблица B), которые не совпадают. Мне еще предстоит использовать этот тип соединения, но все остальные я использую довольно часто. Это соединение записывается следующим образом:

SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL OR B.Key IS NULL

Примеры

Предположим, у нас есть две таблицы, Table_A и Table_B. Данные в этих таблицах показаны ниже:

TABLE_A
  PK Value
---- ----------
   1 FOX
   2 COP
   3 TAXI
   6 WASHINGTON
   7 DELL
   5 ARIZONA
   4 LINCOLN
  10 LUCENT

TABLE_B
  PK Value
---- ----------
   1 TROT
   2 CAR
   3 CAB
   6 MONUMENT
   7 PC
   8 MICROSOFT
   9 APPLE
  11 SCOTCH

-- The results of the seven Joins:

-- INNER JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
       B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
INNER JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7

(5 row(s) affected)

-- LEFT JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   4 LINCOLN    NULL       NULL
   5 ARIZONA    NULL       NULL
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7
  10 LUCENT     NULL       NULL

(8 row(s) affected)

-- RIGHT JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
RIGHT JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11

(8 row(s) affected)

-- OUTER JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11
   5 ARIZONA    NULL       NULL
   4 LINCOLN    NULL       NULL
  10 LUCENT     NULL       NULL

(11 row(s) affected)

-- LEFT EXCLUDING JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK
WHERE B.PK IS NULL

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   4 LINCOLN    NULL       NULL
   5 ARIZONA    NULL       NULL
  10 LUCENT     NULL       NULL
(3 row(s) affected)

-- RIGHT EXCLUDING JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
RIGHT JOIN Table_B B
ON A.PK = B.PK
WHERE A.PK IS NULL

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11

(3 row(s) affected)

-- OUTER EXCLUDING JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.PK = B.PK
WHERE A.PK IS NULL
OR B.PK IS NULL

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11
   5 ARIZONA    NULL       NULL
   4 LINCOLN    NULL       NULL
  10 LUCENT     NULL       NULL

(6 row(s) affected)

Резюмируем

Обратите внимание на ВНЕШНЕЕ СОЕДИНЕНИЕ (OUTER JOIN), что сначала возвращаются внутренние объединенные записи, затем правые соединенные записи, а затем, наконец, левые соединенные записи (по крайней мере, так это сделал мой Microsoft SQL Server; это, конечно, без использования каких-либо ORDER BY).

Я также создал шпаргалку, которую при необходимости можно распечатать:


Источники:

(1) https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins

Tags

Нет комментариев

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.