Sql in join: Joins (SQL Server) — SQL Server
Содержание
SQL JOIN — предложение WHERE против предложения ON
Это очень распространенный вопрос, поэтому этот ответ основан на статье, которую я написал.
Таблица отношений
Учитывая , мы имеем следующее post
и post_comment
таблицы:
post
Имеет следующие записи:
| id | title |
|----|-----------|
| 1 | Java |
| 2 | Hibernate |
| 3 | JPA |
и post_comment
имеет следующие три строки:
| id | review | post_id |
|----|-----------|---------|
| 1 | Good | 1 |
| 2 | Excellent | 1 |
| 3 | Awesome | 2 |
SQL INNER JOIN
Предложение SQL JOIN позволяет связывать строки, которые принадлежат разным таблицам. Например, CROSS JOIN создаст декартово произведение, содержащее все возможные комбинации строк между двумя объединяющимися таблицами.
Хотя CROSS JOIN полезен в определенных сценариях, в большинстве случаев вы хотите объединить таблицы на основе определенных условий. И именно здесь INNER JOIN вступает в игру.
SQL INNER JOIN позволяет нам фильтровать декартово произведение объединения двух таблиц на основе условия, указанного в предложении ON.
SQL INNER JOIN — ON «всегда истинное» условие
Если вы укажете условие «всегда верно», INNER JOIN не будет фильтровать объединенные записи, а набор результатов будет содержать декартово произведение двух объединяющихся таблиц.
Например, если мы выполним следующий запрос SQL INNER JOIN:
SELECT
p.id AS "p.id",
pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 1
Мы получим все комбинации post
и post_comment
записи:
| p.id | pc.id |
|---------|------------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
Итак, если условие предложения ON «всегда истинно», INNER JOIN просто эквивалентно запросу CROSS JOIN:
SELECT
p.id AS "p.id",
pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 1
ORDER BY p.id, pc.id
SQL INNER JOIN — ON «всегда ложное» условие
С другой стороны, если условие предложения ON «всегда ложно», то все объединенные записи будут отфильтрованы, а набор результатов будет пустым.
Итак, если мы выполним следующий запрос SQL INNER JOIN:
SELECT
p.id AS "p.id",
pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 0
ORDER BY p.id, pc.id
Мы не получим никакого результата назад:
| p.id | pc.id |
|---------|------------|
Это потому, что приведенный выше запрос эквивалентен следующему запросу CROSS JOIN:
SELECT
p.id AS "p.id",
pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 0
ORDER BY p.id, pc.id
SQL INNER JOIN — предложение ON с использованием столбцов «Внешний ключ» и «Первичный ключ»
Наиболее распространенным условием предложения ON является то, которое сопоставляет столбец внешнего ключа в дочерней таблице со столбцом первичного ключа в родительской таблице, как показано в следующем запросе:
SELECT
p.id AS "p.id",
pc.post_id AS "pc.post_id",
pc.id AS "pc.id",
p.title AS "p.title",
pc.review AS "pc.review"
FROM post p
INNER JOIN post_comment pc ON pc.post_id = p.id
ORDER BY p.id, pc.id
При выполнении вышеупомянутого запроса SQL INNER JOIN мы получаем следующий набор результатов:
| p.id | pc.post_id | pc.id | p.title | pc.review |
|---------|------------|------------|------------|-----------|
| 1 | 1 | 1 | Java | Good |
| 1 | 1 | 2 | Java | Excellent |
| 2 | 2 | 3 | Hibernate | Awesome |
Таким образом, в набор результатов запроса включаются только записи, соответствующие условию предложения ON. В нашем случае результирующий набор содержит все post
вместе со своими post_comment
записями. Эти post
строки , которые не связаны post_comment
исключены , так как они не могут удовлетворять условию ON Clause.
Опять же, приведенный выше запрос SQL INNER JOIN эквивалентен следующему запросу CROSS JOIN:
SELECT
p.id AS "p.id",
pc.post_id AS "pc.post_id",
pc.id AS "pc.id",
p.title AS "p.title",
pc.review AS "pc.review"
FROM post p, post_comment pc
WHERE pc.post_id = p.id
Не пораженные строки — это те, которые удовлетворяют предложению WHERE, и только эти записи будут включены в набор результатов. Это лучший способ визуализировать, как работает предложение INNER JOIN.
| p.id | pc.post_id | pc.id | p.title | pc.review | | ------ | ------------ | ------- | ----------- | --------- - | | 1 | 1 | 1 | Java | Хорошо | | 1 | 1 | 2 | Java | Отлично | | 1 | 2 | 3 | Java | Высокий | | 2 | 1 | 1 | Спящий | Хорошо | | 2 | 1 | 2 | Спящий | Отлично | | 2 | 2 | 3 | Спящий | Высокий | | 3 | 1 | 1 | JPA | Хорошо | | 3 | 1 | 2 | JPA | Отлично | | 3 | 2 | 3 | JPA | Высокий |
Вывод
Оператор INNER JOIN может быть переписан как CROSS JOIN с предложением WHERE, совпадающим с тем же условием, которое вы использовали в предложении ON запроса INNER JOIN.
Не то чтобы это относится только к ВНУТРЕННЕМУ СОЕДИНЕНИЮ, а не для ВНЕШНЕГО СОЕДИНЕНИЯ
Визуальное представление соединений JOIN в SQL
Добавлено 11 февраля 2016 в 18:00
Сохранить или поделиться
‘JOIN
‘ – ключевое слово в SQL, используемое для запроса данных из двух и более связанных таблиц. Данная статья – это попытка кратко и лаконично объяснить работу с JOIN
себе и всем, кто заинтересован в этом.
Связанные таблицы
Хорошо спроектированная реляционная база данных включает в себя ряд таблиц, содержащих связанные данные. В качестве очень простого примера данных используем пользователей (студентов) и зачисления на курсы:
id | name | course |
---|---|---|
1 | Alice | 1 |
2 | Bob | 1 |
3 | Caroline | 2 |
4 | David | 5 |
5 | Emma | (NULL) |
Код MySQL для создания таблицы:
CREATE TABLE `user` (
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL,
`course` smallint(5) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
Номера курсов связаны с объектами, находящимися в таблице курсов…
id | name |
---|---|
1 | HTML5 |
2 | CSS3 |
3 | JavaScript |
4 | PHP |
5 | MySQL |
Код MySQL для создания таблицы:
CREATE TABLE `course` (
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
Поскольку мы используем таблицы InnoDB и знаем, что user.course и course.id связаны, то можем задать связь внешним ключом:
ALTER TABLE `user`
ADD CONSTRAINT `FK_course`
FOREIGN KEY (`course`) REFERENCES `course` (`id`)
ON UPDATE CASCADE;
В сущности, MySQL будет автоматически:
- перенумеровывать связанные записи в столбце
user.course
при изменениях вcourse.id
; - отклонять любые попытки удалить курс, на который зачислены пользователи.
Важно: эта база данных спроектирована ужасно!
Эта база данных неэффективна. Она нормальна для примера, но студент в ней может быть записан либо никуда, либо только на один курс. В реальной системе такого ограничения быть не должно, для этого можно использовать промежуточную таблицу «регистрация», которая будет связывать любое количество студентов с любым количеством курсов.
INNER JOIN
(или просто JOIN
)
INNER JOIN
является наиболее часто используемым. Он дает набор записей, которые совпадают в обоих таблицах, и в user
, и в course
, то есть все пользователи, зачисленные на курсы:
SELECT user.name, course.name
FROM `user`
INNER JOIN `course` on user.course = course.id;
Результат:
user.name | course.name |
---|---|
Alice | HTML5 |
Bob | HTML5 |
Caroline | CSS3 |
David | MySQL |
LEFT JOIN
А что делать, если нам необходим список всех студентов и их курсов, даже если они не зачислены ни на один курс? LEFT JOIN
даст набор записей, которые соответствуют каждой записи в левой таблице (user
) независимо от соответствия записи в правой таблице (course
):
SELECT user.name, course.name
FROM `user`
LEFT JOIN `course` on user.course = course.id;
user.name | course.name |
---|---|
Alice | HTML5 |
Bob | HTML5 |
Carline | CSS3 |
David | MySQL |
Emma | (NULL) |
Добавив условие
WHERE course.id IS NULL
мы получим список студентов, не зачисленных ни на один курс. И диаграмма для такого запроса будет следующей:
RIGHT JOIN
Возможно, нам потребуется список всех курсов и студентов, даже если никто из них не был зачислен? RIGHT JOIN
дает набор записей, которые соответствуют каждой записи в правой таблице (course
) независимо от соответствия записи в левой таблице (user
):
SELECT user.name, course.name
FROM `user`
RIGHT JOIN `course` on user.course = course.id;
Результат:
user.name | course.name |
---|---|
Alice | HTML5 |
Bob | HTML5 |
Carline | CSS3 |
(NULL) | JavaScript |
(NULL) | PHP |
David | MySQL |
RIGHT JOIN
используется редко, так как вы можете получить тот же результат, используя LEFT JOIN
. Следующий код может быть более эффективным и быстрым для парсинга СУБД:
SELECT user.name, course.name
FROM `course`
LEFT JOIN `user` on user.course = course.id;
Мы могли бы, например, подсчитать количество студентов, обучающихся на каждом курсе:
SELECT course.name, COUNT(user.name)
FROM `course`
LEFT JOIN `user` ON user.course = course.id
GROUP BY course.id;
Результат:
course.name | count() |
---|---|
HTML5 | 2 |
CSS3 | 1 |
JavaScript | 0 |
PHP | 0 |
MySQL | 1 |
OUTER JOIN
(или FULL OUTER JOIN
)
OUTER JOIN
возвращает все записи из обеих таблиц независимо от совпадений. Там где совпадения нет, на недостающей стороне будет содержаться NULL
.
OUTER JOIN
менее полезен по сравнению с INNER
, LEFT
или RIGHT
, и он не реализован в MySQL. Тем не менее, вы можете обойти это ограничение, используя UNION
для LEFT JOIN
и RIGHT JOIN
, например:
SELECT user.name, course.name
FROM `user`
LEFT JOIN `course` on user.course = course.id
UNION
SELECT user.name, course.name
FROM `user`
RIGHT JOIN `course` on user.course = course.id;
Результат:
user.name | course.name |
---|---|
Alice | HTML5 |
Bob | HTML5 |
Carline | CSS3 |
David | MySQL |
Emma | (NULL) |
(NULL) | JavaScript |
(NULL) | PHP |
Вот и всё! Надеюсь этот материал будет кому-то полезен.
Источники:
Теги
JOINSQLБаза данных
Сохранить или поделиться
Руководство по SQL. SELF JOIN. – PROSELYTE
Элемент SELF JOIN используется для объединения таблицы с ней самой таким образом, будто это две разные таблицы, временно переименовывая одну из них.
Запрос и использованием SELF JOIN имеет следующий вид:
SELECT a.имяколонки, b.имя_колонки...
FROM таблица1 a, таблица1 b
WHERE a.общее поле = b.общее поле;
Пример:
Предположим, что у нас есть таблица developers, которая содержит следующие записи:
+----+-------------------+------------+------------+--------+
| ID | NAME | SPECIALTY | EXPERIENCE | SALARY |
+----+-------------------+------------+------------+--------+
| 1 | Eugene Suleimanov | Java | 2 | 2500 |
| 2 | Peter Romanenko | Java | 3 | 3500 |
| 3 | Andrei Komarov | JavaScript | 3 | 2500 |
| 4 | Konstantin Geiko | C# | 2 | 2000 |
| 5 | Asya Suleimanova | UI/UX | 2 | 1800 |
| 6 | Kolya Nikolaev | Javascript | 5 | 3400 |
| 7 | Ivan Ivanov | C# | 1 | 900 |
| 8 | Ludmila Geiko | UI/UX | 2 | 1800 |
+----+-------------------+------------+------------+--------+
Попробуем выполнить следующий запрос:
mysql> SELECT a.ID, a.NAME, a.SALARY
FROM developers a, developers b
WHERE a.SALARY < b.SALARY
AND b.ID = 1;
В результате мы получим следующую таблицу:
+----+------------------+--------+
| ID | NAME | SALARY |
+----+------------------+--------+
| 4 | Konstantin Geiko | 2000 |
| 5 | Asya Suleimanova | 1800 |
| 7 | Ivan Ivanov | 900 |
| 8 | Ludmila Geiko | 1800 |
+----+------------------+--------+
Как мы видим, мы получили всех разработчиков из таблицы developers, зарплата которых ниже зарплаты разработчика с ID = 1 (Eugene Suleimanov).
На этом мы заканчиваем изучение SELF JOIN.
Skillbox Media / SQL JOIN в картинках
Подойдёт, если:
- я хочу выбрать датские фильмы;
- и согласна, что среди них могут быть триллеры;
- но мне не интересны триллеры производства других стран, только датские.
Вот так будет выглядеть SQL-запрос:
SELECT * FROM D LEFT JOIN T ON D.Key=T.Key
И подобающая случаю диаграмма:
Датские любых жанров, а из триллеров только датские
LEFT JOIN (левое внешнее объединение) — то же самое, что LEFT OUTER JOIN.
В результат попадают совпадающие по ключу данные обеих таблиц и все записи из левой таблицы, для которых не нашлось пары в правой.
— А что, если я вообще не фанат триллеров, но датские фильмы мне интересны?
— Тогда к скрипту выше нужно дописать одно условие:
SELECT * FROM D LEFT JOIN T ON D.Key=T.Key WHERE T.Key IS NULL
Дословно T.Key IS NULL означает, что нужно включить в результат только записи, в которых значение ключа для записей из множества триллеров пусто.
— Как это пусто? Ведь у фильма не может быть пустой номер!
— Верно. Думай об этом не как о едином множестве фильмов, а как о парах фильмов из двух групп. Мы берём один фильм из первой группы (датские) и ищем во второй группе (триллеров) для него пару — фильм с таким же номером.
Если пара найдётся (значит, попался датский триллер) — считаем, что T.Key не пустой, иначе он как раз и будет IS NULL.
Диаграмма теперь выглядит так:
Датские — все, кроме триллеров. Триллеры полностью исключаем
Операторы слияния таблиц SQL JOIN в Excel PowerQuery
Смотрите видео к статье:
Или операторы объединения таблиц SQL JOIN в Excel Power Query (начиная с Excel 2016)
Как известно самым популярным и эффективным инструментом работы с табличными данными (или просто таблицами) является программа Microsoft Excel.
При этом также известно, что самым мощным и распространённым языком программирования для работы с табличными данными является язык Structured Query Language = SQL = Язык структурированных запросов
Исходя из этого факта, логично предположить, что Microsoft Excel должен поддерживать язык SQL по умолчанию. Но, как правило, SQL поддерживается только базами данных (СУБД).
Несмотря на это, для Excel (начиная с 2010 версии) появилась бесплатная надстройка Power Query, которая позволяет имитировать часть полезного функционала языка SQL, а именно:
В языке SQL есть очень интересный оператор «SELECT», который позволяет делать запросы к табличным данным в базе данных. В результате запроса возвращается набор данных (выборка из базы данных), удовлетворяющий заданному условию выборки.
Как правило, выборка данных делается из нескольких таблиц в базе данных. Для связи таблиц в языке программирования SQL существует оператор «JOIN», который выполняет различные операции соединения реляционных таблиц (в основе этого принципа лежат законы реляционной алгебры)
Различают следующие виды оператора «JOIN»:
- INNER JOIN — Оператор внутреннего соединения двух таблиц
- LEFT OUTER JOIN — Оператор левого внешнего соединения двух таблиц
- RIGHT OUTER JOIN — Оператор правого внешнего соединения двух таблиц
- FULL OUTER JOIN — Оператор полного внешнего соединения двух таблиц
- CROSS JOIN — Оператор перекрёстного соединения (декартово произведение) двух таблиц
С выходом надстройки Power Query для Excel (это один из инструментов уровня Self-Service BI) в Excel появилась поддержка функционала всех видов операторов «JOIN» языка SQL:
Рассмотрим операторов «JOIN» в Excel на примерах:
Представим, что у нас в Excel есть две Таблицы: A «Люди» и B «Города»
Теперь давайте объединим данные таблицы с помощью различных операторов «JOIN»:
(объединяем таблицы через столбцы: A.Cityid = B.id)
Оператор INNER JOIN вернет следующий результат:
Оператор LEFT JOIN вернет следующий результат:
Оператор RIGHT JOIN вернет следующий результат:
Оператор FULL OUTER JOIN вернет следующий результат:
Оператор CROSS JOIN вернет следующий результат:
В надстройке Power Query для Excel данная функция «JOIN» называется «Слияние» — слияние запросов, где:
Оператору слияния INNER JOIN соответствует тип соединения: Внутреннее (только совпадающие строки)
Оператору слияния LEFT JOIN соответствует тип соединения: Внешнее соединение слева (все из первой таблицы, совпадающие из второй)
Оператору слияния RIGHT JOIN соответствует тип соединения: Внешнее соединение справа (все из второй таблицы, совпадающие из первой)
Оператору слияния FULL OUTER JOIN соответствует тип соединения: Полное внешнее (все строки из обеих таблиц)
Оператора слияния CROSS JOIN в интерфейсе Power Query нет, но его можно создать из оператора слияния FULL OUTER JOIN, убрав связи таблиц
Скачать Excel файл с примерами объединения SQL JOIN (функция «Слияние» в Power Query) можно скачать здесь
Пошаговая инструкция использования функции «Слияние»/«Объединения» в Power Query находится в видеоуроке к данной статье
T-SQL.RU | Join Hints
Join Hints (LOOP | HASH | MERGE | REMOTE) — Подсказки оптимизатору запросов на выбор определенной стратегии соединения двух таблиц (используется в SELECT, UPDATE и DELETE).
Оптимизатор запросов SQL Server обычно автоматически выбирает наилучший план выполнения запроса. Поэтому подсказки, в том числе <подсказки_по_соединению>, рекомендуется использовать только опытным пользователям и администраторам базы данных в случае крайней необходимости.
Без явного указания аргумента (LOOP | HASH | MERGE | REMOTE) оптимизатор выбирает, на его взгляд, самый оптимальный план. Но мы всегда можем повлиять на него, если явно укажем подсказку.
Ниже разберем каждый из аргументов подробнее.
Loop Join
Соединение LOOP JOIN, называемое также nested iteration, использует одну таблицу в качестве внешней (на графическом плане она является верхней), а второй в качестве внутренней (нижней). LOOP JOIN построчно сравнивает внешнюю таблицу с внутренней. В цикле для каждой внешней строки производится сканирование внутренней таблицы и выводятся совпадающие строки.
В простейшем случае во время поиска целиком сканируется таблица или индекс (naive nested loops join). Если при поиске используется индекс, то такой поиск называется index nested loops join. Если индекс создается в качестве части плана запроса (и уничтожается после завершения запроса), то он называется temporary index nested loops join. Оптимизатор сам выбирает один из этих поисков.
LOOP JOIN является особенно эффективным в случае, когда внешняя таблица сравнительно невелика, а внутренняя гораздо больше и для неё существуют индексы. В запросах с небольшим объёмом строк, index nested loops join превосходит как MERGE JOIN, так и HASH JOIN. Однако в больших запросах LOOP JOIN часто являются не лучшим вариантом.
Для демонстрации создадим 2 тестовые таблицы:
CREATE TABLE LoopLeftTable (ID INT) CREATE TABLE LoopRightTable (ID INT IDENTITY PRIMARY KEY)
И посмотрим план запроса:
SELECT * FROM LoopLeftTable INNER jOIN LoopRightTable ON LoopLeftTable.ID=LoopRightTable.ID
Как и описано выше оптимизатор выбрал LOOP JOIN. Но если мы вставим в таблицу достаточно большое кол-во строк, то оптимизатор откажется от соединения LOOP JOIN:
INSERT INTO LoopLeftTable SELECT 1 GO 10000
Оптимизатор при выполнении запроса выбрал HASH JOIN, так как посчитал, что стимость этого соединения будет ниже. Но если мы не доверяем оптимизатору то можем явно указать ему использовать LOOP JOIN:
SELECT * FROM LoopLeftTable INNER LOOP jOIN LoopRightTable ON LoopLeftTable.ID=LoopRightTable.ID
Кстати, если сравнить стоимость выполнения запроса выбранного оптимизатором и наш с подсказкой, то можно убедиться, что оптимизатор действительно выбрал верный план. (http://msdn.microsoft.com/en-us/library/ms191318.aspx)
Аргумент LOOP не может указываться вместе с параметрами RIGHT или FULL в качестве типа соединения.
Merge Join
Merge Join требует сортировки обоих наборов входных данных по столбцам слияния, которые определены предложениями равенства (ON) предиката соединения. (т.е. если мы имеем предикат соединения «T1.a = T2.b», таблица T1 должна быть отсортирована по T1.a, а таблица T2 должна быть сортирована по T2.b).
Так как каждый набор входных данных сортируется, оператор Merge Join получает строку из каждого набора входных данных и сравнивает их. Например, для операций INNER JOIN строки возвращаются в том случае, если они равны. Если они не равны, строка с меньшим значением не учитывается, и из этого набора входных данных берется другая строка. Этот процесс повторяется, пока не будет выполнена обработка всех строк.
MERGE JOIN может поддерживать слияние «многие ко многим». В этом случае, при каждом соединении двух строк нужно сохранять копию каждой строки второго входного потока. Это позволяет, при последующем обнаружении в первом входном потоке дубликатов строк, воспроизвести сохраненные строки. С другой стороны, если будет ясно, что следующая строка первого входного потока не является дубликатом, от сохраненных строк можно отказаться. Такие строки сохраняются во временно таблице базы tempdb. Размер дискового пространства, который для этого необходим, зависит от числа дубликатов во втором входном потоке.
MERGE JOIN «один ко многим» всегда будет эффективнее слияния «многие ко многим», поскольку для него не требуется временная таблица. Для того, что бы задействовать слиянием «один ко многим», оптимизатор должен иметь возможность определить, что один из входных потоков состоит из уникальных строк. Как правило, это означает, что у такого входного потока существует уникальный индекс или в плане запроса присутствует явным образом оператор (например, сортировка при DISTINCT или группировка), который гарантирует, что строки на входе будут уникальны.
Merge Join — очень быстрая операция, но она может оказаться ресурсоемкой, если требуется выполнение операций сортировки. Однако на больших объёмах при наличии индексов и предварительной сортировке, соединение слиянием является самым быстрым из доступных алгоритмов соединения.
Для демонстрации создадим 2 таблицы очень похожие на те, что были созданы в примере с LOOP JOIN:
CREATE TABLE MergeLeftTable (ID INT IDENTITY PRIMARY KEY) CREATE TABLE MergeRightTable (ID INT IDENTITY PRIMARY KEY)
Если посмотреть какой план выбрал оптимизатор на пустых таблицах, если в качестве запроса указать:
SELECT MergeLeftTable.ID FROM MergeLeftTable INNER jOIN MergeRightTable ON MergeLeftTable.ID=MergeRightTable.ID
то окажется, что опять используется LOOP JOIN.
Можно явно указать оптимизатору использовать MERGE JOIN:
SELECT MergeLeftTable.ID FROM MergeLeftTable INNER MERGE jOIN MergeRightTable ON MergeLeftTable.ID=MergeRightTable.ID
Но оптимизатор сам выберет для этих таблиц MERGE JOIN, если наполнить их (таблицы) хотя бы небольшим кол-ом данных:
INSERT INTO MergeLeftTable DEFAULT VALUES GO 40 INSERT INTO MergeRightTable DEFAULT VALUES GO 40
Тогда первый запрос для этих таблиц без подсказки выполнится по плану с MERGE JOIN: (http://msdn.microsoft.com/en-us/library/ms190967.aspx)
Hash Join
Hash Join — более эффективен при работе с большими наборами данных и даже тогда, когда таблицы не отсортированы по столбцам, по которым производится соединение. Hash Join распараллеливается и масштабируется лучше любого другого соединения и сильно выигрывает при большой производительности информационных хранилищ.
Соединение происходит с использованием хеширования, вычесляя хеш записей из меньшей таблицы (Build-таблица) и вставляя их в хеш-таблицу, затем обрабатывается большая таблица (Probe-таблица) по одной записи, сканируя хеш-таблицу для поиска совпадений.
Создадим две таблицы для демонстрации:
CREATE TABLE HashLeftTable (ID INT) CREATE TABLE HashRightTable (ID INT)
Если посмотреть план запроса:
SELECT HashLeftTable.ID FROM HashLeftTable INNER jOIN HashRightTable ON HashLeftTable.ID=HashRightTable.ID
То увидем, что оптимизатор выбрал Hash Join:
Но если оптимизатор выбрал другой план, но мы явно желаем использовать хеш-объединение, то мы так же можем «подсказать» это оптимизатору:
SELECT HashLeftTable.ID FROM HashLeftTable INNER HASH jOIN HashRightTable ON HashLeftTable.ID=HashRightTable.ID
Hash Join бывают 3х видов:
- In-Memory Hash Join Когда таблицы небольшого размера и могут полностью быть помещенны в память
- Grace Hash Join Если размер таблиц превышает максимально допустимый объем памяти, то хэш-соединение проводится в несколько шагов.
- Recursive Hash Join Этот вид объединения используется для сложных таблиц и для таблиц, которые являются очень большими и требуют многоуровневое соединение в несколько шагов.
(http://msdn.microsoft.com/en-us/library/ms189313.aspx)
Remote Join
Remote Join может быть использован только при операциях INNER JOIN.
Remote Join задает, что операция соединения проводится на странице таблицы, расположенной справа. Данный аргумент удобно использовать в случае, когда таблица, расположенная слева, является локальной, а справа располагается удаленная таблица (Linked Server). Аргумент REMOTE может использоваться в случае, когда в таблице слева содержится меньшее количество строк, чем в таблице справа. Если таблица, расположенная справа, является локальной, то операция соединения также проводится локально. Если обе таблицы являются удаленными, но
расположены в различных источниках данных, то при задании аргумента REMOTE операция соединения проводится на странице таблицы, расположенной справа. Если обе таблицы являются удаленными таблицами в одном источнике данных, то аргумент REMOTE не требуется.
Как и в придыдущих случаях, мы можем явно указать оптимизатору использовать необходимое объединение:
SELECT HashLeftTable.ID FROM HashLeftTable INNER REMOTE jOIN HashRightTable ON HashLeftTable.ID=HashRightTable.ID
По теме:
SQL JOIN — Dofactory
Объяснение SQL JOIN
Запрос SQL JOIN объединяет записи из двух таблиц.
A JOIN находит связанные значения столбцов в двух таблицах.
Запрос может содержать ноль, одну или несколько операций JOIN.
Задача: Перечислите всех поставщиков с их продуктами.
скопировано в буфер обмена
ВЫБЕРИТЕ CompanyName, ProductName ОТ поставщика ПРИСОЕДИНЯЙТЕСЬ к продукту поставщика.Id = Product.SupplierId
ВЫБЕРИТЕ CompanyName, ProductName
ОТ поставщика
ПРИСОЕДИНЯЙТЕСЬ к продукту НА Supplier.Id = Product.SupplierId
Попробуйте вживую
- (INNER) JOIN: выберите записи, значения которых совпадают в обеих таблицах.
- ПОЛНОЕ (ВНЕШНЕЕ) СОЕДИНЕНИЕ: выбирает все записи, соответствующие либо левой, либо правой записям таблицы.
- LEFT (OUTER) JOIN: выберите записи из первой (самой левой) таблицы с соответствующими записями правой таблицы.
- RIGHT (OUTER) JOIN: выберите записи из второй (самой правой) таблицы с соответствующими записями левой таблицы.
Все ключевые слова INNER и OUTER необязательны.
Подробная информация об этих операциях JOIN доступна ниже и на последующих страницах.
Синтаксис JOIN.
ВЫБЕРИТЕ имена столбцов ИЗ имя-таблицы1 ПРИСОЕДИНИТЬСЯ имя-таблицы2 ON имя-столбца1 = имя-столбца2 ГДЕ условие
Синтаксис INNER JOIN.
ВЫБЕРИТЕ имена столбцов ИЗ имя-таблицы1 ВНУТРЕННЕЕ СОЕДИНЕНИЕ имя-таблицы2 ON имя-столбца1 = имя-столбца2 ГДЕ условие
JOIN — это то же самое, что и INNER JOIN; ключевое слово INNER необязательно.
INNER JOIN — это наиболее часто используемый тип операции JOIN.
SQL ВЫБРАТЬ СОЕДИНЕНИЕ
КЛИЕНТ |
---|
Идентификатор |
Имя |
Фамилия |
Город |
Страна |
Телефон |
ЗАКАЗ |
---|
OrderNumber |
CustomerId |
TotalAmount |
Проблема: Список всех заказов с информацией о клиенте.
скопировано в буфер обмена
ВЫБРАТЬ OrderNumber, TotalAmount, FirstName, LastName, City, Country ОТ [Заказ] ПРИСОЕДИНЯЙТЕСЬ к клиенту НА [Заказ] .CustomerId = Customer.Id
ВЫБРАТЬ OrderNumber, TotalAmount, FirstName, LastName, City, Country
ОТ [Заказ]
ПРИСОЕДИНЯЙТЕСЬ к клиенту НА [Заказ] .CustomerId = Customer.Id
Попробуйте вживую
В этом примере могло быть полезно использовать псевдонимы таблиц для [Order] и Customer.
Результат: 830 записей.
Номер заказа | Всего | Имя | Фамилия | Город | Страна |
---|---|---|---|---|---|
542378 | 440,00 | Пол | Анрио | Реймс | Франция |
542379 | 1863.40 | Карин | Джозефс | Мюнстер | Германия |
542380 | 1813,00 | Марио | Понты | Рио-де-Жанейро | Бразилия |
542381 | 670,80 | Мэри | Савли | Лион | Франция |
542382 | 3730.00 | Паскаль | Картрейн | Шарлеруа | Бельгия |
542383 | 1444,80 | Марио | Понты | Рио-де-Жанейро | Бразилия |
542384 | 625,20 | Ян | Ван | Берн | Швейцария |
SQL SELECT JOIN с 3 таблицами
Проблема: Список всех заказов, отсортированных по номеру заказа, с названиями продуктов, количеством и ценами.
ПРОДУКТ |
---|
Идентификатор |
Название продукта |
Идентификатор поставщика |
Цена за единицу |
Упаковка |
Исчезла с производства |
ProductId |
UnitPrice |
Количество |
ORDER |
---|
Id |
OrderDate |
OrderNumber |
скопировано в буфер обмена
ВЫБЕРИТЕ O.OrderNumber, CONVERT (date, O.OrderDate) AS Date, P.ProductName, I.Quantity, I.UnitPrice ОТ [Заказ] O ПРИСОЕДИНЯЙТЕСЬ к OrderItem I ON O.Id = I.OrderId ПРИСОЕДИНЯЙТЕСЬ к продукту P ON P.Id = I.ProductId ЗАКАЗ ПО O.OrderNumber
ВЫБРАТЬ O.O.OrderNumber, CONVERT (date, O.OrderDate) AS Date,
P.ProductName, I.Quantity, I.UnitPrice
ОТ [Заказ] O
ПРИСОЕДИНЯЙТЕСЬ к OrderItem I ON O.Id = I.OrderId
ПРИСОЕДИНЯЙТЕСЬ к продукту P ON P.Id = I.ProductId
ЗАКАЗ ОТ О.Номер заказа
Попробуйте вживую
Этот запрос выполняет две операции JOIN с 3 таблицами.
O, I и P — псевдонимы таблицы.
Дата — это псевдоним столбца.
Результат: 2155 записей
Номер заказа | Дата | Название продукта | Кол-во | Цена за единицу |
---|---|---|---|---|
542378 | 04.07.2012 00:00:00 | Queso Cabrales | 12 | 14.00 |
542378 | 04.07.2012 00:00:00 | Сингапурский Хоккиен Фрид Ми | 10 | 9,80 |
542378 | 04.07.2012 00:00:00 | Моцарелла ди Джованни | 5 | 34,80 |
542379 | 05.07.2012 00:00:00 | Тофу | 9 | 18.60 |
542379 | 05.07.2012 00:00:00 | Сушеные яблоки Манджимуп | 40 | 42,40 |
542380 | 8.07.2012 00:00:00 | Похлебка из моллюсков из Новой Англии Джека | 10 | 7,70 |
542380 | 8.07.2012 00:00:00 | Сушеные яблоки Манджимуп | 35 | 42.40 |
542380 | 8.07.2012 00:00:00 | Соус Луизиана Огненный Острый Перец | 15 | 16,80 |
542381 | 8.07.2012 00:00:00 | Knäckebröd Густава | 6 | 16,80 |
542381 | 8.07.2012 00:00:00 | Равиоли Анджело | 15 | 15.60 |
542381 | 8.07.2012 00:00:00 | Соус Луизиана Огненный Острый Перец | 20 | 16,80 |
542382 | 09.07.2012 00:00:00 | Мармелад сэра Родни | 40 | 64,80 |
542382 | 09.07.2012 00:00:00 | Geitost | 25 | 2.00 |
SQL Join: Обзор типов SQL-соединений с примерами — Управление базами данных — Блоги
SQL JOIN — это предложение, которое используется для объединения нескольких таблиц и извлечения данных на основе общего поля в реляционных базах данных. Специалисты по базам данных используют нормализацию для обеспечения и улучшения целостности данных. В различных формах нормализации данные распределяются по нескольким логическим таблицам.Эти таблицы используют ссылочные ограничения — первичный ключ и внешние ключи — для обеспечения целостности данных в таблицах SQL Server. На изображении ниже мы видим процесс нормализации базы данных.
Понимание различных типов SQL JOIN
SQL JOIN генерирует значимые данные путем объединения нескольких реляционных таблиц. Эти таблицы связаны с помощью ключа и имеют отношения «один к одному» или «один ко многим». Чтобы получить правильные данные, вы должны знать требования к данным и правильные механизмы соединения.SQL Server поддерживает несколько объединений, и каждый метод имеет определенный способ извлечения данных из нескольких таблиц. На изображении ниже указаны поддерживаемые соединения SQL Server.
Внутреннее соединение SQL
Внутреннее соединение SQL включает строки из таблиц, для которых выполнены условия соединения. Например, на приведенной ниже диаграмме Венна внутреннее соединение возвращает совпадающие строки из Таблицы A и Таблицы B.
В приведенном ниже примере обратите внимание на следующее:
- У нас есть две таблицы — [Сотрудники] и [Адрес].
- SQL-запрос объединяется в столбцы [Сотрудники]. [EmpID] и [Адрес]. [ID].
Выходные данные запроса возвращают записи сотрудников для EmpID, которые существуют в обеих таблицах.
Внутреннее соединение возвращает совпадающие строки из обеих таблиц; поэтому оно также известно как Equi join. Если мы не укажем ключевое слово inner, SQL Server выполнит операцию внутреннего соединения.
В другом типе внутреннего соединения, тета-соединении, мы не используем оператор равенства (=) в предложении ON.Вместо этого мы используем операторы неравенства, такие как <и>.
ВЫБРАТЬ * ИЗ Table1 T1, Table2 T2 ГДЕ T1.Цена При самосоединении SQL Server соединяет таблицу с самим собой. Это означает, что имя таблицы появляется дважды в предложении from. Самостоятельное присоединение к SQL
Ниже у нас есть таблица [Emp], в которой есть данные о сотрудниках, а также их менеджеры. Самосоединение полезно для запроса иерархических данных. Например, в таблице сотрудников мы можем использовать самообъединение, чтобы узнать имя каждого сотрудника и имя его руководителя.
Приведенный выше запрос помещает самосоединение в таблицу [Emp]. Он соединяет столбец EmpMgrID со столбцом EmpID и возвращает совпадающие строки.
перекрестное соединение SQL
При перекрестном соединении SQL Server возвращает декартово произведение из обеих таблиц. Например, на изображении ниже мы выполнили перекрестное соединение для таблиц A и B.
Перекрестное соединение объединяет каждую строку из таблицы A с каждой строкой, доступной в таблице B. Таким образом, результат также известен как декартово произведение обеих таблиц.На изображении ниже обратите внимание на следующее:
- Таблица [Сотрудник] содержит три строки для Emp ID 1,2 и 3.
- Таблица [Адрес] содержит записи для Emp ID 1,2,7 и 8.
В выходных данных перекрестного объединения строка 1 таблицы [Сотрудник] объединяется со всеми строками таблицы [Адрес] и следует тому же шаблону для остальных строк.
Если первая таблица содержит x строк, а вторая таблица имеет n строк, перекрестное соединение дает x * n количество строк в выходных данных.Вам следует избегать перекрестного соединения для больших таблиц, потому что оно может возвращать огромное количество записей, а SQL Server требует большой вычислительной мощности (ЦП, память и ввод-вывод) для обработки таких обширных данных.
Внешнее соединение SQL
Как мы объясняли ранее, внутреннее соединение возвращает совпадающие строки из обеих таблиц. При использовании внешнего соединения SQL оно не только выводит список совпадающих строк, но также возвращает несопоставленные строки из других таблиц. Непревзойденная строка зависит от левого, правого или полного ключевых слов.
На изображении ниже в общих чертах описываются левое, правое и полное внешнее соединение.
Левое внешнее соединение
Левое внешнее соединение SQL возвращает совпадающие строки обеих таблиц вместе с несовпадающими строками из левой таблицы. Если запись из левой таблицы не имеет совпадающих строк в правой таблице, она отображает запись со значениями NULL.
В приведенном ниже примере левое внешнее соединение возвращает следующие строки:
- Сопоставленные строки: Emp ID 1 и 2 существует как в левой, так и в правой таблицах.
- Несопоставленная строка: Emp ID 3 не существует в правой таблице. Следовательно, в выходных данных запроса у нас есть значение NULL.
Соединение правое наружное
Правое внешнее соединение SQL возвращает совпадающие строки обеих таблиц вместе с несовпадающими строками из правой таблицы. Если запись из правой таблицы не имеет совпадающих строк в левой таблице, она отображает запись со значениями NULL.
В приведенном ниже примере у нас есть следующие выходные строки:
- Соответствующие строки: Emp ID 1 и 2 существует в обеих таблицах; следовательно, эти строки совпадают.
- Несопоставленные строки: в правой таблице у нас есть дополнительные строки для Emp ID 7 и 8, но эти строки недоступны в левой таблице. Следовательно, мы получаем значение NULL в правом внешнем соединении для этих строк.
Полное внешнее соединение
Полное внешнее соединение возвращает следующие строки на выходе:
- Соответствующие строки между двумя таблицами.
- Несопоставленные строки, аналогичные левому внешнему соединению: значения NULL для несовпадающих строк из правой таблицы.
- Несопоставленные строки, аналогичные правому внешнему соединению: нулевые значения для несовпадающих строк из левой таблицы.
SQL объединяет несколько таблиц
В предыдущих примерах мы использовали две таблицы в запросе SQL для выполнения операций соединения. Чаще всего мы объединяем несколько таблиц вместе, и это возвращает соответствующие данные.
В приведенном ниже запросе используется несколько внутренних соединений.
ИСПОЛЬЗОВАНИЕ [AdventureWorks2019] ИДТИ ВЫБРАТЬ д. [BusinessEntityID] ,п.[Имя] , стр. [MiddleName] , стр. [Фамилия] , д. [JobTitle] , д. [Название] AS [Отдел] , d. [GroupName] , edh. [Дата начала] ОТ [HumanResources]. [Сотрудник] e INNER JOIN [Человек]. [Человек] p НА стр. [BusinessEntityID] = e. [BusinessEntityID] ВНУТРЕННЕЕ СОЕДИНЕНИЕ [HumanResources]. [EmployeeDepartmentHistory] edh НА e. [BusinessEntityID] = edh. [BusinessEntityID] INNER JOIN [HumanResources]. [Department] d НА edh.[DepartmentID] = d. [DepartmentID] ГДЕ edh.EndDate ЕСТЬ NULL ИДТИ
Давайте проанализируем запрос, выполнив следующие шаги:
- Промежуточный результат 1: Первое внутреннее соединение между таблицей [HumanResources]. [Employees] и [Person]. [Person].
- Промежуточный результат 2: Внутреннее соединение между таблицей [Промежуточный результат 1] и [HumanResources]. [EmployeeDepartmentHistory].
- Промежуточный результат 3: Внутреннее соединение между [Промежуточный результат 2] и [HumanResources].Таблица [Отделение].
После выполнения запроса с несколькими объединениями оптимизатор запросов подготавливает план выполнения. Он подготавливает оптимизированный по стоимости план выполнения, удовлетворяющий условиям соединения с использованием ресурсов — например, в приведенном ниже фактическом плане выполнения мы можем посмотреть на несколько вложенных циклов (внутреннее соединение) и хэш-соответствие (внутреннее соединение), объединяющее данные из нескольких соединяемых таблиц. .
значений NULL и SQL объединяет
Предположим, что у нас есть значения NULL в столбцах таблицы, и мы объединяем таблицы в этих столбцах.Соответствует ли SQL Server значениям NULL?
Значения NULL не соответствуют друг другу. Таким образом, SQL Server не может вернуть соответствующую строку. В приведенном ниже примере у нас есть NULL в столбце EmpID таблицы [Сотрудники]. Следовательно, в выходных данных он возвращает соответствующую строку только для [EmpID] 2.
Мы можем получить эту строку NULL в выходных данных в случае внешнего соединения SQL, потому что она также возвращает несовпадающие строки.
SQL присоединяйтесь к лучшим практикам
В этой статье мы исследовали различные типы соединений SQL.Вот несколько важных рекомендаций, которые следует помнить и применять при использовании соединений SQL.
- Внутренние соединения выводят совпадающие строки из условия соединения в обеих таблицах.
- Cross join возвращает декартово произведение обеих таблиц.
- Внешнее соединение возвращает совпадающие и несовпадающие строки в зависимости от левого, правого и полного ключевых слов.
- Самосоединение SQL объединяет таблицу с собой.
- Вы всегда должны использовать псевдоним таблицы при использовании объединений в запросах.
- Всегда используйте имя из двух частей [псевдоним таблицы]. [Столбец] для столбцов в запросах.
- В случае нескольких соединений SQL в запросе следует использовать логический порядок таблиц таким образом, чтобы удовлетворить ваши требования к данным и минимизировать поток данных между различными операторами плана выполнения.
- Вы можете комбинировать несколько соединений, таких как внутреннее соединение, внешнее соединение и самосоединение. Однако вы должны использовать объединения и их заказы для получения требуемых данных.
SQL объединяется с использованием WHERE или ON | Средний уровень SQL
Начиная с этого места? Этот урок является частью полного руководства по использованию SQL для анализа данных. Проверьте начало.
В этом уроке мы рассмотрим:
Фильтрация в предложении ON
Обычно фильтрация обрабатывается в предложении WHERE
после того, как две таблицы уже были объединены. Однако возможно, что вы захотите отфильтровать одну или обе таблицы перед тем, как присоединится к ним.Например, вы хотите создавать совпадения между таблицами только при определенных обстоятельствах.
Используя данные Crunchbase, давайте еще раз посмотрим на пример LEFT JOIN
из предыдущего урока (на этот раз мы добавим предложение ORDER BY
):
ВЫБРАТЬ companies.permalink AS companies_permalink,
company.name AS имя_компании,
acquisitions.company_permalink AS acquisitions_permalink,
acquisitions.acquired_at AS Дата_ приобретения
ИЗ учебника.crunchbase_companies компании
LEFT JOIN tutorial.crunchbase_acquisitions acquisitions
ON companies.permalink = acquisitions.company_permalink
ЗАКАЗАТЬ ПО 1
Сравните следующий запрос с предыдущим, и вы увидите, что все в таблице tutorial.crunchbase_acquisitions
было объединено на , за исключением для строки, для которой company_permalink
составляет '/ company / 1000memories'
:
ВЫБРАТЬ companies.permalink AS companies_permalink,
компании.назовите AS имя_компании,
acquisitions.company_permalink AS acquisitions_permalink,
acquisitions.acquired_at AS Дата_ приобретения
ОТ tutorial.crunchbase_companies компании
LEFT JOIN tutorial.crunchbase_acquisitions acquisitions
ON companies.permalink = acquisitions.company_permalink
И acquisitions.company_permalink! = '/ Company / 1000memories'
ЗАКАЗАТЬ ПО 1
Что происходит выше, так это то, что условный оператор AND ...
вычисляется до того, как произойдет соединение.Вы можете думать об этом как о предложении WHERE
, которое применяется только к одной из таблиц. Вы можете сказать, что это происходит только в одной из таблиц, потому что постоянная ссылка 1000memories все еще отображается в столбце, извлеченном из другой таблицы:
Фильтрация в предложении WHERE
Если вы переместите тот же фильтр в предложение WHERE
, вы заметите, что фильтр применяется после объединения таблиц. В результате строка 1000memories присоединяется к исходной таблице, но затем она полностью отфильтровывается (в обеих таблицах) в предложении WHERE
перед отображением результатов.
ВЫБРАТЬ companies.permalink AS companies_permalink,
company.name AS имя_компании,
acquisitions.company_permalink AS acquisitions_permalink,
acquisitions.acquired_at AS Дата_ приобретения
ОТ tutorial.crunchbase_companies компании
LEFT JOIN tutorial.crunchbase_acquisitions acquisitions
ON companies.permalink = acquisitions.company_permalink
ГДЕ acquisitions.company_permalink! = '/ Company / 1000memories'
ИЛИ acquisitions.company_permalink ЕСТЬ NULL
ЗАКАЗАТЬ ПО 1
Вы можете видеть, что строка 1000memories не возвращается (она была бы между двумя выделенными строками ниже).Также обратите внимание, что фильтрация в предложении WHERE
также может фильтровать нулевые значения, поэтому мы добавили дополнительную строку, чтобы обязательно включить нули.
Отточите свои навыки работы с SQL
Для этого набора практических задач мы собираемся представить новый набор данных: tutorial.crunchbase_investments
. Эта таблица также получена из Crunchbase и содержит большую часть той же информации, что и данные tutorial.crunchbase_companies
. Однако он имеет другую структуру: он содержит одну строку на инвестиции .В каждой компании может быть несколько инвестиций — даже возможно, что один инвестор может инвестировать в одну и ту же компанию несколько раз. Имена столбцов говорят сами за себя. Важно то, что company_permalink
в таблице tutorial.crunchbase_investments
сопоставляется с постоянной ссылкой в таблице tutorial.crunchbase_companies
. Имейте в виду, что некоторые случайные данные были удалены из этой таблицы для этого урока.
Очень вероятно, что вам нужно будет провести некоторый исследовательский анализ этой таблицы, чтобы понять, как вы можете решить следующие проблемы.
Практическая задача
Напишите запрос, который показывает название компании, «статус» (находится в таблице «Компании») и количество уникальных инвесторов в этой компании. Порядок по количеству инвесторов от наибольшего к наименьшему. Ограничение только для компаний в штате Нью-Йорк.
Попробуй это
Посмотреть ответ
Практическая задача
Напишите запрос, в котором будут перечислены инвесторы по количеству компаний, в которые они вложили средства.Включите строку для компаний без инвестора и закажите от большинства компаний до наименьшего.
Попробуй это
Посмотреть ответ
Типы соединений SQL, объясненные в визуальных материалах
Последнее изменение: 9 августа 2021 г.
Объединение двух наборов данных с помощью инструментов SQL или SQL можно выполнить с помощью JOINS. JOIN — это инструкция SQL в предложении FROM вашего запроса, которая используется для идентификации запрашиваемых таблиц и способов их объединения.
Первичный и внешний ключи
Обычно в реляционной базе данных данные организованы в различные таблицы, состоящие из атрибутов (столбцов) и записей (строк). В каждой таблице существует столбец, который является первичным ключом , который является столбцом, в котором каждая запись уникальным образом представляет одну строку в этой таблице. Обычно это столбец идентификатора (сокращенно от идентификатора). Столбец в таблице, который устанавливает связь с первичным ключом другой таблицы через общие значения, называется внешним ключом .Внешние ключи также обычно называются идентификаторами, но с добавлением имени таблицы, на которую указывает ссылка.
Эта концепция применяется при объединении двух или более таблиц вместе с помощью JOIN. В приведенном ниже примере у нас есть две таблицы: таблица пользователей (таблица 1) и таблица событий (таблица 2). Мы хотим объединить две таблицы вместе, чтобы вместе с данными о событиях получать данные о пользователях. Реальным примером этого может быть случай, если у вас есть данные из инструмента CRM, такого как Salesforce, содержащего пользователей, которые являются платными клиентами (Таблица 1), и инструмента анализа событий, такого как Mixpanel, который отслеживает всех пользователей, выполнивших действие в вашем продукте ( Таблица 2).
Обратите внимание, что между двумя таблицами есть общий столбец (измерение), выделенный зеленым цветом, User ID. В таблице пользователей столбец ID — это идентификатор пользователя, и это первичный ключ для этой таблицы, тогда как в таблице событий столбец User_ID является внешним ключом, поскольку этот столбец ссылается на столбец ID в таблице Users. Мы можем использовать это отношение, чтобы объединить две таблицы вместе, чтобы собрать информацию о пользователях и событиях в одной таблице.
Знакомьтесь, присоединяется
Существует три распространенных способа объединения любых двух или более таблиц, о которых мы сначала поговорим: Внешнее соединение , Внутреннее соединение и Левое соединение .Используя приведенные выше примеры таблиц User и Event , давайте рассмотрим некоторые примеры объединений…
Наружное соединение
Допустим, вы хотите иметь таблицу, содержащую все ваши данные о пользователях и событиях вместе.
Вы можете использовать внешнее соединение , чтобы объединить таблицы. Внешнее соединение объединяет столбцы из всех таблиц в одном или нескольких общих измерениях, когда это возможно, и включает все данные из всех таблиц.
Чтобы получить более подробную информацию о внешнем соединении, щелкните здесь.
Внутреннее соединение
Что, если вы хотите иметь таблицу, содержащую только пользователей, выполнивших действие?
Вы можете использовать внутреннее соединение , чтобы объединить таблицы. Внутреннее соединение объединяет столбцы в общем измерении (первые N столбцов), когда это возможно, и включает данные только для столбцов, которые имеют одинаковые значения в общих столбцах N. В этом примере User ID будет общим измерением, используемым для внутреннего соединения.
Чтобы получить более подробную информацию о внутреннем соединении, щелкните здесь.
Соединение слева
А что, если вы хотите иметь таблицу, содержащую все данные пользователей и только действия, которые эти пользователи сделали? Действия, выполненные другими пользователями, не указанными в таблице пользователей, не должны быть включены?
Вы можете использовать левое соединение , чтобы объединить таблицы. Левое соединение объединяет столбцы в общем измерении (первые N столбцов), когда это возможно, возвращая все строки из первой таблицы с совпадающими строками в следующих друг за другом таблицах.Результатом является NULL в следующих друг за другом таблицах, когда совпадений нет. В этом случае мы сделаем User Table первой (левой) таблицей, которая будет использоваться для левого соединения.
Для получения более подробной информации о левом соединении щелкните здесь.
Союз и Крест Присоединяйтесь
В дополнение к этим общим типам соединений, есть несколько методов, которые приведут к появлению дополнительных строк в вашей выходной таблице, а также большего количества столбцов. Два из этих типов соединения называются Union и Cross Join .Эти типы соединений, вероятно, не подходят для приведенных выше примеров таблиц, но для этой статьи мы все равно можем использовать их, чтобы увидеть, как эти объединения работают. Объединение Union Join будет складывать таблицы друг на друга, в результате чего появляются новые строки.
Чтобы получить более подробную информацию о Union Join, щелкните здесь.
Хороший вариант использования для этого — если вы хотите объединить две таблицы, добавляя их, а не объединяя их. В результате перекрестного соединения будет получена таблица со всеми возможными комбинациями строк ваших таблиц вместе.Это может привести к огромным размерам таблиц, поэтому пользоваться им следует с осторожностью.
Чтобы получить более подробную информацию о перекрестном соединении, щелкните здесь.
Cross Joins, вероятно, будет использоваться только тогда, когда ваши таблицы содержат отдельные значения, которые вы хотите объединить без общего измерения.
Краткая шпаргалка
Написано:
Тим Миллер
Проверено:
Мэтт Дэвид
SQL: ПРИСОЕДИНЯЕТСЯ к
В этом руководстве по SQL объясняется, как использовать SQL JOINS с синтаксисом, наглядными иллюстрациями и примерами.
Описание
SQL JOINS используются для извлечения данных из нескольких таблиц. SQL JOIN выполняется всякий раз, когда две или более таблицы перечислены в операторе SQL.
Существует 4 различных типа SQL-соединений:
- ВНУТРЕННЕЕ СОЕДИНЕНИЕ SQL (иногда называемое простым соединением)
- SQL LEFT OUTER JOIN (иногда называется LEFT JOIN)
- SQL RIGHT OUTER JOIN (иногда называется RIGHT JOIN)
- ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ SQL (иногда называется ПОЛНОЕ СОЕДИНЕНИЕ)
Итак, давайте обсудим синтаксис SQL JOIN, посмотрим на визуальные иллюстрации SQL JOINS и рассмотрим несколько примеров.
DDL / DML для примеров
Если вы хотите следовать этому руководству, получите DDL для создания таблиц и DML для заполнения данных. Тогда попробуйте примеры в своей базе данных!
Получить DDL / DML
SQL INNER JOIN (простое соединение)
Скорее всего, вы уже написали оператор SQL, который использует SQL INNER JOIN. Это наиболее распространенный тип соединения SQL. SQL INNER JOINS возвращает все строки из нескольких таблиц, в которых выполнено условие соединения.
Синтаксис
Синтаксис INNER JOIN в SQL:
ВЫБРАТЬ столбцы ИЗ table1 INNER JOIN table2 НА table1.column = table2.column;
Визуальная иллюстрация
На этой визуальной диаграмме SQL INNER JOIN возвращает заштрихованную область:
SQL INNER JOIN вернет записи, в которых пересекаются table1 и table2 .
Пример
Давайте рассмотрим пример использования INNER JOIN в запросе.
В этом примере у нас есть таблица с именем клиентов со следующими данными:
customer_id | фамилия | имя | избранное_сайт |
---|---|---|---|
4000 | Джексон | Джо | techonthenet.com |
5000 | Смит | Джейн | digminecraft.com |
6000 | Фергюсон | Саманта | bigactivities.com |
7000 | Рейнольдс | Аллен | checkyourmath.com |
8000 | Андерсон | Пейдж | НЕТ |
9000 | Джонсон | Дерек | techonthenet.com |
И таблица под названием заказы со следующими данными:
order_id | customer_id | дата заказа |
---|---|---|
1 | 7000 | 18.04.2016 |
2 | 5000 | 18.04.2016 |
3 | 8000 | 19.04.2016 |
4 | 4000 | 2016/04/20 |
5 | НЕТ | 01.05.2016 |
Введите следующий оператор SQL:
Попытайся
ВЫБРАТЬ клиентов.customer_id, orders.order_id, orders.order_date ОТ клиентов INNER JOIN заказы ВКЛ. Customers.customer_id = orders.customer_id ЗАКАЗАТЬ ПО customers.customer_id;
Будет выбрано 4 записи. Вот результаты, которые вы должны увидеть:
customer_id | order_id | дата заказа |
---|---|---|
4000 | 4 | 2016/04/20 |
5000 | 2 | 18.04.2016 |
7000 | 1 | 18.04.2016 |
8000 | 3 | 19.04.2016 |
В этом примере будут возвращены все строки из таблиц customers и orders , где есть совпадающее значение customer_id в таблицах customers и orders .
Строки, где customer_id равно 6000 и 9000, в таблице customers будут опущены, поскольку их нет в обеих таблицах. Строка, в которой order_id равно 5 из таблицы orders , будет опущена, поскольку customer_id со значением NULL не существует в таблице customers .
Старый синтаксис
В заключение стоит упомянуть, что приведенный выше пример INNER JOIN можно переписать с использованием старого неявного синтаксиса следующим образом (но мы по-прежнему рекомендуем использовать синтаксис ключевого слова INNER JOIN):
Попытайся
ВЫБРАТЬ клиентов.customer_id, orders.order_id, orders.order_date ОТ клиентов, заказы ГДЕ customers.customer_id = orders.customer_id ЗАКАЗАТЬ ПО customers.customer_id;
SQL ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ
Другой тип соединения называется LEFT OUTER JOIN. Этот тип соединения возвращает все строки из ЛЕВОЙ таблицы, указанной в условии ON, и только тех строк из другой таблицы, в которых объединенные поля равны (условие соединения выполнено).
Синтаксис
Синтаксис LEFT OUTER JOIN в SQL:
ВЫБРАТЬ столбцы ИЗ table1 LEFT [OUTER] JOIN table2 НА table1.столбец = table2.column;
В некоторых базах данных ключевое слово OUTER опускается и записывается просто как LEFT JOIN.
Визуальная иллюстрация
На этой визуальной диаграмме SQL LEFT OUTER JOIN возвращает заштрихованную область:
SQL LEFT OUTER JOIN вернет все записи из table1 и только те записи из table2 , которые пересекаются с table1 .
Пример
Теперь давайте посмотрим на пример, который показывает, как использовать LEFT OUTER JOIN в операторе SELECT.
Используя ту же таблицу customers , что и в предыдущем примере:
customer_id | фамилия | имя | избранное_сайт |
---|---|---|---|
4000 | Джексон | Джо | techonthenet.com |
5000 | Смит | Джейн | digminecraft.com |
6000 | Фергюсон | Саманта | большой деятельности.com |
7000 | Рейнольдс | Аллен | checkyourmath.com |
8000 | Андерсон | Пейдж | НЕТ |
9000 | Джонсон | Дерек | techonthenet.com |
А заказывает таблицу со следующими данными:
order_id | customer_id | дата заказа |
---|---|---|
1 | 7000 | 18.04.2016 |
2 | 5000 | 18.04.2016 |
3 | 8000 | 19.04.2016 |
4 | 4000 | 2016/04/20 |
5 | НЕТ | 01.05.2016 |
Введите следующий оператор SQL:
Попытайся
ВЫБРАТЬ клиентов.customer_id, orders.order_id, orders.order_date ОТ клиентов LEFT OUTER JOIN заказы ВКЛ. Customers.customer_id = orders.customer_id ЗАКАЗАТЬ ПО customers.customer_id;
Будет выбрано 6 записей. Вот результаты, которые вы должны увидеть:
customer_id | order_id | дата заказа |
---|---|---|
4000 | 4 | 2016/04/20 |
5000 | 2 | 18.04.2016 |
6000 | НЕТ | НЕТ |
7000 | 1 | 18.04.2016 |
8000 | 3 | 19.04.2016 |
9000 | НЕТ | НЕТ |
В этом примере LEFT OUTER JOIN будут возвращены все строки из таблицы customers и только те строки из таблицы orders , в которых объединенные поля равны.
Если значение customer_id в таблице customers не существует в таблице orders , все поля в таблице orders будут отображаться как NULL в результирующем наборе. Как видите, строки, где customer_id, , 6000 и 9000, будут включены в ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ, но поля order_id и order_date отображают NULL.
SQL ПРАВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ
Другой тип соединения называется SQL RIGHT OUTER JOIN.Этот тип соединения возвращает все строки из ПРАВОЙ таблицы, указанной в условии ON, и только тех строк из другой таблицы, в которых объединенные поля равны (условие соединения выполнено).
Синтаксис
Синтаксис ПРАВОГО ВНЕШНЕГО СОЕДИНЕНИЯ в SQL:
ВЫБРАТЬ столбцы ИЗ table1 RIGHT [OUTER] JOIN table2 НА table1.column = table2.column;
В некоторых базах данных ключевое слово OUTER опускается и записывается просто как RIGHT JOIN.
Визуальная иллюстрация
На этой визуальной диаграмме SQL RIGHT OUTER JOIN возвращает заштрихованную область:
SQL RIGHT OUTER JOIN вернет все записи из table2 и только те записи из table1 , которые пересекаются с table2 .
Пример
Теперь давайте рассмотрим пример, показывающий, как использовать RIGHT OUTER JOIN в операторе SELECT.
Используя ту же таблицу customers , что и в предыдущем примере:
customer_id | фамилия | имя | избранное_сайт |
---|---|---|---|
4000 | Джексон | Джо | techonthenet.com |
5000 | Смит | Джейн | digminecraft.com |
6000 | Фергюсон | Саманта | bigactivities.com |
7000 | Рейнольдс | Аллен | checkyourmath.com |
8000 | Андерсон | Пейдж | НЕТ |
9000 | Джонсон | Дерек | techonthenet.com |
А заказывает таблицу со следующими данными:
order_id | customer_id | дата заказа |
---|---|---|
1 | 7000 | 18.04.2016 |
2 | 5000 | 18.04.2016 |
3 | 8000 | 19.04.2016 |
4 | 4000 | 2016/04/20 |
5 | НЕТ | 01.05.2016 |
Введите следующий оператор SQL:
Попытайся
ВЫБРАТЬ клиентов.customer_id, orders.order_id, orders.order_date ОТ клиентов RIGHT OUTER JOIN заказы ВКЛ. Customers.customer_id = orders.customer_id ЗАКАЗАТЬ ПО customers.customer_id;
Будет выбрано 5 записей. Вот результаты, которые вы должны увидеть:
customer_id | order_id | дата заказа |
---|---|---|
NULL | 5 | 01.05.2016 |
4000 | 4 | 2016/04/20 |
5000 | 2 | 18.04.2016 |
7000 | 1 | 18.04.2016 |
8000 | 3 | 19.04.2016 |
Этот пример RIGHT OUTER JOIN вернет все строки из таблицы orders и только те строки из таблицы customers , в которых объединенные поля равны.
Если значение customer_id в таблице orders не существует в таблице customers , все поля в таблице customers будут отображаться как NULL в результирующем наборе. Как видите, строка, в которой order_id равно 5, будет включена в ПРАВИЛЬНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ, но в поле customer_id отображается NULL.
ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ SQL
Другой тип соединения называется ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ SQL. Этот тип соединения возвращает все строки из таблицы LEFT и RIGHT со значениями NULL в местах, где условие соединения не выполняется.
Синтаксис
Синтаксис SQL FULL OUTER JOIN :
ВЫБРАТЬ столбцы ИЗ table1 FULL [OUTER] JOIN table2 НА table1.column = table2.column;
В некоторых базах данных ключевое слово OUTER опускается и записывается просто как FULL JOIN.
Визуальная иллюстрация
На этой визуальной диаграмме SQL FULL OUTER JOIN возвращает заштрихованную область:
SQL FULL OUTER JOIN вернет все записи из table1 и table2 .
Пример
Давайте рассмотрим пример, показывающий, как использовать FULL OUTER JOIN в операторе SELECT.
Используя ту же таблицу customers , что и в предыдущем примере:
customer_id | фамилия | имя | избранное_сайт |
---|---|---|---|
4000 | Джексон | Джо | techonthenet.com |
5000 | Смит | Джейн | digminecraft.com |
6000 | Фергюсон | Саманта | bigactivities.com |
7000 | Рейнольдс | Аллен | checkyourmath.com |
8000 | Андерсон | Пейдж | НЕТ |
9000 | Джонсон | Дерек | techonthenet.com |
А заказывает таблицу со следующими данными:
order_id | customer_id | дата заказа |
---|---|---|
1 | 7000 | 18.04.2016 |
2 | 5000 | 18.04.2016 |
3 | 8000 | 19.04.2016 |
4 | 4000 | 2016/04/20 |
5 | НЕТ | 01.05.2016 |
Введите следующий оператор SQL:
Попытайся
ВЫБРАТЬ клиентов.customer_id, orders.order_id, orders.order_date ОТ клиентов ЗАКАЗЫ FULL OUTER JOIN ВКЛ. Customers.customer_id = orders.customer_id ЗАКАЗАТЬ ПО customers.customer_id;
Будет выбрано 7 записей. Вот результаты, которые вы должны увидеть:
customer_id | order_id | дата заказа |
---|---|---|
NULL | 5 | 01.05.2016 |
4000 | 4 | 2016/04/20 |
5000 | 2 | 18.04.2016 |
6000 | НЕТ | НЕТ |
7000 | 1 | 18.04.2016 |
8000 | 3 | 19.04.2016 |
9000 | НЕТ | НЕТ |
В этом примере FULL OUTER JOIN будут возвращены все строки из таблицы orders и все строки из таблицы customers .Если условие соединения не выполняется, значение NULL будет расширено до этих полей в наборе результатов. Это означает, что если значение customer_id в таблице customers не существует в таблице orders , все поля в таблице orders будут отображаться как NULL в результирующем наборе. Кроме того, если значение customer_id в таблице orders не существует в таблице customers , все поля в таблице customers будут отображаться как NULL в наборе результатов.
Как видите, строки, в которых customer_id, , 6000 и 9000, будут включены, но поля order_id и order_date для этих записей содержат значение NULL. Строка, в которой order_id равно 5, также будет включена, но поле customer_id для этой записи имеет значение NULL.
Как соединить две таблицы в SQL
Запросы данных из нескольких таблиц очень распространены при работе с реляционными базами данных.Это несложно, если вы знаете, как использовать для этого специальные операторы SQL. В этой статье вы узнаете, как объединить две таблицы с помощью WHERE и специального оператора JOIN, а также узнаете, как фильтровать строки в наборе результатов.
Как запросить отдельную таблицу
Во-первых, напомню, как выбирать данные из одной таблицы. Рассмотрим следующую таблицу: продукт
:
id | наименование | цена |
---|---|---|
1 | Умные часы Erin | 234.00 |
2 | Умные часы Sun | 455,00 |
3 | Smartband Eli | 300,00 |
4 | Smartband Белый | 124,00 |
Чтобы выбрать данные из всех столбцов и всех строк в этой таблице, вы можете использовать запрос:
ВЫБЕРИТЕ id, имя, цену ОТ продукта;
В этом простом запросе имена столбцов, из которых вы хотите получить данные, перечислены после SELECT
.Далее идет ключевое слово ИЗ
и имя таблицы, в которой хранятся данные.
Вы также можете фильтровать строки, чтобы возвращать только те записи, которые соответствуют заданным критериям. Взгляните на следующий код SQL:
ВЫБЕРИТЕ название, цену ОТ ПРОДУКТА ГДЕ ценаВ данном случае набор результатов состоит всего из двух строк с названием столбца и ценой
:
наименование | цена |
---|---|
Умные часы Erin | 234.00 |
Smartband Белый | 124,00 |
Столбцы перечислены после SELECT
, тогда ключевое слово FROM
помогает указать таблицу, из которой вы извлекаете данные. В конце запроса за ключевым словом WHERE
следует условие фильтрации. В этом примере условие сравнивает значение в столбце цена
с 250,00. Запрос возвращает сведения о продукте, только если цена этого продукта меньше 250.00.
Запрос данных из нескольких таблиц с помощью WHERE
Реляционные базы данных состоят из нескольких таблиц, которые ссылаются друг на друга. Строки из одной таблицы относятся к определенным строкам в другой таблице, которые связаны некоторым столбцом (столбцами) идентификатора. Теперь мы посмотрим, как объединить данные из одной таблицы с данными из другой таблицы.
Рассмотрим следующие две таблицы, товар
и категория
, в базе данных о товарах на складе:
товар
id | название_продукта | цена | category_id |
---|---|---|---|
1 | умные часы | 235.00 | 2 |
2 | кирпичей | 26,70 | 3 |
3 | лампа | 128,00 | 2 |
4 | диван | 3200.00 | 1 |
5 | рабочий стол | 1350.00 | 1 |
6 | удлинитель | 29,00 | 2 |
категория
id | название_категории |
---|---|
1 | мебель |
2 | электроника |
3 | игрушки |
Допустим, вам нужны некоторые данные из этой складской базы данных, такие как название продуктов, цена и их соответствующие категории.Вы можете объединить строки из таблицы , продукта
со строками из таблицы категории
, используя предложение WHERE. Взгляните на запрос ниже:
ВЫБЕРИТЕ product.product_name, product.price, category.category_name ОТ продукта, категории ГДЕ product.category_id = category.id;
Вот результат:
название_продукта | цена | название_категории |
---|---|---|
умные часы | 235.00 | электроника |
кирпичи | 26,70 | игрушки |
лампа | 128,00 | электроника |
диван | 3200.00 | мебель |
рабочий стол | 1350.00 | мебель |
удлинитель | 29,00 | электроника |
SELECT
в этом запросе перечисляет столбцы из обеих таблиц: product_name
и price
из таблицы product
и category_name
из таблицы category
.Каждому имени столбца предшествует имя соответствующей таблицы, разделенное точкой.
Далее имена таблиц перечислены после ключевого слова FROM
, разделенных запятыми.
Последняя часть этого запроса — это WHERE
с условием, определяющим, как объединить строки из обеих таблиц. Здесь значения столбца category_id
из таблицы product
соответствуют значениям в столбце id из таблицы category
, и строки объединяются, когда значения равны ( product.category_id = category.id
). Умные часы в таблице , продукт
имеет идентификатор категории 2. То же значение в столбце id
в таблице категория
указывает на «игрушки», как выделено синим цветом выше.
Если в обеих таблицах есть столбцы с одинаковыми именами, их необходимо различать при присвоении им имени в SELECT
. Вы делаете это, называя таблицу, ставя точку, а затем имя столбца. В нашем примере, однако, таблицы имеют разные имена столбцов, у которых нет общих имен.Мы можем использовать только имена столбцов в SELECT
, не указывая, из каких таблиц они берутся, как в запросе ниже:
ВЫБЕРИТЕ product_name, price, category_name ОТ продукта, категории ГДЕ product.category_id = category.id;
Использование WHERE
— это один из способов запроса данных из нескольких таблиц. Это более старый стандарт SQL; Хотя он все еще доступен, он редко используется. В следующем разделе мы рассмотрим другой метод.
Запрос данных из нескольких таблиц с помощью JOIN
Сегодня наиболее распространенным методом объединения данных из нескольких таблиц является специальный оператор JOIN
, также известный как INNER JOIN
.Чтобы увидеть, как это работает, мы будем использовать те же две таблицы из базы данных хранилища, которые вы можете найти ниже для удобства.
товар
id | наименование | цена | category_id |
---|---|---|---|
1 | умные часы | 235,00 | 2 |
2 | кирпичей | 26,70 | 3 |
3 | лампа | 128.00 | 2 |
4 | диван | 3200.00 | 1 |
5 | рабочий стол | 1350.00 | 1 |
6 | удлинитель | 29,00 | 2 |
категория
id | название |
---|---|
1 | мебель |
2 | электроника |
3 | игрушки |
Взгляните на следующий запрос, который присваивает категорию из таблицы категорию
каждому названию продукта в таблице product
.
ВЫБРАТЬ product.name AS product_name, имя_категории AS имя_категории ОТ ПРОДУКТА ПРИСОЕДИНЯЙТЕСЬ к категории НА product.category_id = category.id;
Соединение выполняется оператором JOIN
. В предложении FROM
за именем первой таблицы ( продукт
) следует ключевое слово JOIN
, затем имя второй таблицы ( категория
). Затем следует ключевое слово ON и условие объединения строк из разных таблиц.Имя категории присваивается на основе столбца id
таблицы d, что эквивалентно category_id в таблице product (product.category_id = category.id).
Вот результат:
название_продукта | название_категории |
---|---|
умные часы | электроника |
кирпичи | игрушки |
лампа | электроника |
диван | мебель |
письменный стол | мебель |
удлинитель | электроника |
Умные часы имеют значение category_id
, равное 2.В столбце id таблицы , , категория ,
, значение 2 связано с электроникой, поэтому смарт-часы относятся к электронике.
Использование JOIN Оператор
— наиболее распространенный метод объединения нескольких таблиц в базе данных. В статье «Иллюстрированное руководство по SQL INNER JOIN» я подробно рассказываю об этом операторе. Статья «SQL INNER JOIN, объясненная простыми словами» также углубляется в эту тему. Как упоминалось ранее, оператор INNER JOIN
эквивалентен JOIN
; вы можете использовать их как взаимозаменяемые.
Выбор данных из таблиц с помощью JOIN и WHERE
Использование операторов JOIN
для извлечения данных из нескольких таблиц также упрощает фильтрацию набора результатов. Взгляните на следующий запрос, который является вариантом предыдущего запроса и основан на тех же данных:
ВЫБРАТЬ product.name AS product_name, имя_категории AS имя_категории ОТ ПРОДУКТА ПРИСОЕДИНЯЙТЕСЬ к категории НА product.category_id = category.id ГДЕ category.name! = ’Toys’;
Вот результат:
название_продукта | название_категории |
---|---|
умные часы | электроника |
лампа | электроника |
диван | мебель |
письменный стол | мебель |
удлинитель | электроника |
Первая часть этого запроса такая же, как и последняя.Однако в этом запросе исключаются товары категории «игрушки». Мы фильтруем строки в наборе результатов, используя предложение WHERE
, чтобы проверить, не является ли категория отличной от «игрушки» ( category.name! = ’Toys’
).
Для получения дополнительной практики JOIN в SQL я предлагаю вам прочитать статью «Как практиковать SQL JOIN» или посмотреть видео «Основы SQL JOIN» из серии «Мы изучаем SQL».
Есть также другие операторы JOIN
. Помимо JOIN
или INNER JOIN
, существуют операторы LEFT JOIN
, RIGHT JOIN
и FULL JOIN
.Узнайте больше о них в разделе «SQL JOINs для начинающих» и узнайте, как их использовать, в нашем курсе «Основы SQL».
Объединение таблиц в SQL
Мы видели, как вы можете получить полную информацию об объектах, объединив несколько таблиц, которые ссылаются друг на друга в реляционной базе данных. Вы можете сделать это, используя WHERE
или JOIN
. Чтобы узнать больше о различиях между этими методами, я рекомендую очень интересную статью «В чем разница между наличием нескольких таблиц в FROM и использованием JOIN?».
Я дал вам только беглое представление об этой теме, так что продолжайте учиться!
Обзор типов соединений SQL и учебное пособие
В этой статье будет представлен обзор SQL-соединения и рассмотрены все типы SQL-соединений, включая внутреннее, собственное, перекрестное и внешнее. Для внутренних объединений мы будем обсуждать объединения Equi и Theta.
Возможность комбинировать результаты из связанных строк из нескольких таблиц — важная часть проектирования системы реляционных баз данных.В SQL Server это достигается с помощью предложения SQL join. Это характерно для традиционных систем реляционных баз данных, где одна таблица содержит информацию, относящуюся к другим таблицам с общим значением ключа. Используя соединение SQL, вы можете легко выполнять запросы к связанным наборам данных из нескольких таблиц с этими общими ключами.
Цель этой статьи — предоставить вам базовые знания и примеры, которые потребуются для эффективного использования SQL-соединения в любой среде базы данных.
Что такое соединение SQL?
SQL-соединение — это особая форма генерации значимых данных путем объединения нескольких таблиц, связанных друг с другом с помощью «ключа». Обычно реляционные таблицы должны иметь уникальный столбец, и этот столбец используется для создания отношений с одной или несколькими другими таблицами. Если вам нужен набор результатов, включающий связанные строки из нескольких таблиц, вам нужно будет использовать SQL-соединение для этого столбца.
Ниже перечислены различные типы соединения SQL.
- Внутреннее соединение SQL
- Equi join
- Неравномерное соединение (тета-соединение)
- Внешнее соединение SQL
- Левое соединение SQL или левое внешнее соединение
- Правое соединение SQL или правое внешнее соединение
- Полное соединение SQL или полное внешнее соединение
- Перекрестное соединение SQL
- Самостоятельное присоединение к SQL
Примечание: Ключевое слово external не является обязательным.Это означает, что вы можете указать ключевое слово «внешний» или нет, что не влияет на выполнение запроса.
Например,
Типы соединений SQL
Внутреннее соединение SQL
Самая простая и наиболее распространенная форма соединения — это внутреннее соединение SQL, используемое по умолчанию для типов соединения SQL, используемых в большинстве систем управления базами данных. Это соединение SQL по умолчанию, которое вы получаете, когда используете ключевое слово join отдельно.
Результат внутреннего соединения SQL включает строки из обеих таблиц, в которых выполняются условия соединения.
Синтаксис:
SELECT ColumnList из LeftTable L ВНУТРЕННЕЕ соединение RightTable R ON L.Column = R.Column |
Примечание: Очень легко визуализировать запрос соединения в виде диаграммы Венна, где каждая из таблиц представлена пересекающимися фигурами. Пересечение фигур, где таблицы перекрываются, — это строки, в которых выполняется условие.Для этой цели часто используются уникальные столбцы (ID), когда условие, которое должно быть выполнено, — это совпадение идентификаторов строк.
Equi join:
Эквивалентное соединение — это наиболее распространенная форма внутреннего соединения SQL, используемая на практике. Если соединение содержит оператор равенства, например =, тогда это равносоединение .
В следующем примере возвращаются все совпадающие имена состояний и stateProvinceID.
ВЫБРАТЬ ОТЛИЧИТЕЛЬНЫЙ A.StateProvinceID, S.Name ОТ Person.Address A внутреннее соединение Person.StateProvince S На A.StateProvinceID = S.StateProvinceID |
Theta join (неэквивалентное соединение):
Как правило, это соединение Theta, используемое для указания операторов или условий (предложение ON в SQL). На практике это редко используемые типы соединения SQL. В большинстве случаев соединение будет использовать условие неравенства, например >
ВЫБРАТЬ p1.FirstName, p2. Имя ОТ PErson.Person p1 INNER присоединиться к PErson.Person p2 ON len (p1.FirstName)> len (p2.FirstName); |
Самостоятельное присоединение к SQL
Самостоятельное соединение SQL — это механизм присоединения таблицы к самой себе. Вы могли бы использовать самосоединение, когда хотите создать результирующий набор, объединяющий записи в таблице с некоторыми другими записями из той же таблицы.
В качестве примера самосоединения SQL рассмотрим таблицу сотрудников, в которой перечислены менеджеры, потому что они также являются сотрудниками, и мы хотели бы взглянуть на набор результатов, который возвращает всех сотрудников и указывает, кто их менеджеры.
SELECT e.ename, e.empno, m.ename as manager, e.mgr FROM emp e, emp m ГДЕ e.mgr = m.empno |
перекрестное соединение SQL
CROSS-соединение возвращает все строки для всех возможных комбинаций двух таблиц. Он генерирует все строки из левой таблицы, которые затем объединяются со всеми строками из правой таблицы. Этот тип соединения также известен как декартово произведение (A * B).
Например, если в левой таблице 100 строк, а в правой — 100, то результат перекрестного соединения даст 10 000 строк.
SELECT e.BusinessEntityID, d.Name AS Department FROM HumanResources.Employee AS e CROSS join HumanResources.Department AS d |
Внешнее соединение SQL
При объединении таблиц с помощью внутреннего соединения SQL на выходе возвращаются только совпадающие строки из обеих таблиц. При использовании внешнего соединения SQL не только будут перечислены совпадающие строки, но и будут перечислены несопоставленные строки из других таблиц.
Левое внешнее соединение SQL вернет все записи из левой таблицы в предложении соединения, независимо от совпадающих записей в правой таблице. Левое внешнее соединение SQL включает строки, в которых выполняется условие, плюс все строки из таблицы слева, где условие не выполняется. Поля из правой таблицы без совпадений будут отображаться как нулевые значения.
Синтаксис:
SELECT ColumnList from LeftTable L LEFT join RightTable R ON L.Столбец = R.Column Где R.Column NULL |
В следующем примере объединяются две таблицы Product и SalesOrderDetail на ProductID и сохраняются несовпадающие строки из левой таблицы. Таблица Product сопоставляется с таблицей SalesOrderDetail в столбцах ProductID каждой таблицы. Все продукты, заказанные и не заказанные, появятся в наборе результатов.
SELECT p.Name, so.SalesOrderID FROM Производство.Product p LEFT OUTER присоединиться к Sales.SalesOrderDetail так ON p.ProductID = so.ProductID ORDER BY p.Name; |
Правое внешнее соединение вернет все записи в правой таблице в предложении соединения, независимо от совпадающих записей в левой таблице. Использование правого внешнего соединения SQL включает все строки из таблицы справа. Правильное внешнее соединение SQL считается особым случаем, и многие базы данных не поддерживают правильные соединения.Как правило, правое соединение SQL можно переписать как левое соединение SQL, просто изменив порядок таблиц в запросе. В этом случае поля из левой таблицы без совпадений будут отображать нулевые значения.
Синтаксис:
SELECT ColumnList from LeftTable L RIGHT join RightTable R ON L.Column = R.Column Где L.Column равно NULL |
В следующем примере две таблицы объединяются на TerritoryID (SalesTerritory) и сохраняются несопоставленные строки из правой таблицы (SalesPerson).Таблица SalesTerritory сопоставляется с таблицей SalesPerson в столбце TerritoryID каждой таблицы. В результирующем наборе появляются все продавцы, независимо от того, назначена ли им территория.
ВЫБРАТЬ s.Name AS Territory, p.BusinessEntityID FROM Sales.SalesTerritory s ПРАВО ВНЕШНЕЕ присоединиться к Sales.SalesPerson p ON s.TerritoryID = p.TerritoryID; |
Внешнее соединение SQL , как вы уже могли ожидать, вернет все строки в обеих таблицах.Если строки в одной из таблиц не совпадают, в поле отображается нулевое значение. Полное внешнее соединение SQL сочетает в себе эффекты левых соединений SQL и правых соединений SQL. Многие базы данных не поддерживают реализацию полных внешних соединений SQL.
Синтаксис:
ВЫБРАТЬ ColumnList из LeftTable L ПОЛНОЕ ВНЕШНЕЕ соединение RightTable R ON L.Column = R.Колонка |
В следующем примере возвращается имя продукта, имя любого соответствующего заказа на продажу в таблице SalesOrderDetail из базы данных AdventureWorks2014. Он также возвращает все заказы на продажу, в которых нет продуктов, перечисленных в таблице Product, и любые продукты с заказом на продажу, отличным от того, который указан в таблице Product.
ВЫБЕРИТЕ p.Name, s.SalesOrderID ИЗ Производство.Product p FULL OUTER присоединиться к Sales.SalesOrderDetail s ON p.ProductID = s.ProductID ORDER BY p.Name; |
Сводка
В этой статье мы обсудили большинство важных аспектов SQL-соединений и рассмотрели различные типы SQL-соединений. Мы также продемонстрировали несколько быстрых примеров и примеров того, как мы можем извлекать данные из связанных таблиц из базы данных Adventureworks2016 и как эти таблицы на самом деле получают эту связь с помощью этих ключей с помощью соединений SQL.
На этом пока все. Надеюсь, вам понравилась эта статья о типах соединения SQL. Не стесняйтесь задавать любые вопросы в комментариях ниже.