Содержание

Оператор SQL INNER JOIN: синтаксис, примеры

Оператор SQL INNER JOIN формирует таблицу из записей двух или нескольких таблиц. Каждая строка из первой (левой) таблицы, сопоставляется с каждой строкой из второй (правой) таблицы, после чего происходит проверка условия. Если условие истинно, то строки попадают в результирующую таблицу. В результирующей таблице строки формируются конкатенацией строк первой и второй таблиц.

Оператор SQL INNER JOIN имеет следующий синтаксис:

SELECT
    column_names [,... n]
FROM
    Table_1 INNER JOIN Table_2
ON condition

Условие для сравнения задается в операторе ON.


Примеры оператора SQL INNER JOINИмеются две таблицы:

Authors — содержит в себе информацию об авторах книг:

AuthorIDAuthorName
1
Bruce Eckel
2Robert Lafore
3Andrew Tanenbaum

Books — содержит в себе информацию о названии книг:

BookIDBookName
3Modern Operating System
1Thinking in Java
3Computer Architecture
4Programming in Scala

В таблице Books поле BookID являются внешним ключом и ссылаются на таблицу Authors.

Пример 1. Используя оператор SQL INNER JOIN вывести на экран, какими авторами были написаны какие из книг:

SELECT *
FROM Authors INNER JOIN Books
ON Authors.AuthorID = Books.BookID

В данном запросе оператора SQL INNER JOIN условие сравнения — это равенство полей AuthorID и BookID. В результирующую таблицу не попадет книга под названием Programming in Scala, так как значение ее BookID не найдет равенства ни с одной строкой AuthorID.

Результирующая таблица будет выглядеть следующим образом:

Authors.AuthorIDAuthors.AuthorNameBooks.BookIDBooks.BookName
3Andrew Tanenbaum3Modern Operating System
1Bruce Eckel1Thinking in Java
3Andrew Tanenbaum3Computer Architecture

Команды JOIN, INNER JOIN, LEFT JOIN, RIGHT JOIN — связывание таблиц

Команды JOIN, INNER JOIN, LEFT JOIN, RIGHT JOIN используются для связывания таблиц по определенным полям связи.

Синтаксис

SELECT поля FROM имя_таблицы
LEFT JOIN имя_связанной_таблицы ON условие_связи 
WHERE условие_выборки

Примеры

Все примеры будут по таблицам

countries и cities, если не сказано иное.

Таблица countries:

id
айди
name
имя
1Беларусь
2Россия
3Украина

Таблица cities:

id
айди
name
имя
country_id
айди страны
1Минск1
2Витебск1
3Москва2
4Питер2
5Лондон0

Пример . LEFT JOIN

В данном примере …:

SELECT
	cities.id as city_id, cities.name as city_name, cities.country_id as city_country_id,
	countries.id as country_id, countries.name as country_name
FROM cities
LEFT JOIN countries ON countries.id=cities.country_id

SQL запрос выберет следующие строки:

city_id
айди города
city_name
название города
city_country_id
айди страны
country_id
айди страны
country_name
название страны
1Минск11Беларусь
2Витебск11Беларусь
3
Москва22Россия
4Питер22Россия
5Лондон0NULL

Пример . RIGHT JOIN

В данном примере … Лондон не выберется, а Украина наоборот

SELECT
	cities.id as city_id, cities.name as city_name, cities.country_id as city_country_id,
	countries.id as country_id, countries.name as country_name
FROM cities
RIGHT JOIN countries ON countries.id=cities.country_id

SQL запрос выберет следующие строки:

city_id
айди города
city_name
название города
city_country_id
айди страны
country_id
айди страны
country_name
название страны
1Минск11Беларусь
2Витебск11Беларусь
3Москва22Россия
4Питер22Россия
NULLNULLNULL3Украина

Пример . INNER JOIN

В данном примере … Лондон и Украина не выберется

SELECT
	cities.id as city_id, cities.name as city_name, cities.country_id as city_country_id,
	countries.id as country_id, countries.name as country_name
FROM cities
INNER JOIN countries ON countries.id=cities.country_id

SQL запрос выберет следующие строки:

city_id
айди города
city_name
название города
city_country_id
айди страны
country_id
айди страны
country_name
название страны
1Минск11Беларусь
2Витебск11Беларусь
3Москва22Россия
4Питер22Россия

Объединение таблиц при запросе (JOIN) в SQL

С помощью команды SELECT можно выбрать данные не только из одной таблицы, но и нескольких. Такая задача появляется довольно часто, потому что принято разносить данные по разным таблицам в зависимости от хранимой в них информации. К примеру, в одной таблице хранится информация о пользователях, во второй таблице о должностях компании, а в третьей и четвёртой о поставщиках и клиентах. Данные разбивают на таблицы так, чтобы с одной стороны получить самую высокую скорость выполнения запроса, а с другой стороны избежать ненужных объединений, которые снижают производительность.

Чем больше столбцов в таблице — тем сильнее падает скорость выборки из неё. Поэтому стараются делать в каждой таблице не больше 5-10 столбцов. Но чем сильнее данные разбиваются на разные таблицы, тем больше придётся делать объединений внутри запросов, что тоже снизит скорость получения выборки и увеличит нагрузку на базу.

Приведём пример запроса с объединением данных из двух таблиц. Для этого предположим, что существует две таблицы. Первая таблица будет иметь название USERS и будет иметь два столбца: ID и именами пользователей:
+-----------+
|   USERS   |
+-----------+
| ID | NAME |
+----+------+
| 1  | Мышь |
+----+------+
| 2  | Кот  |
+----+------+
Вторая таблица будет называться FOOD и будет содержать два столбца: USER_ID и NAME. В этой таблице будет содержаться список любимых блюд пользователей из первой таблицы. В столбце USER_ID содержится ID пользователя, а в столбце PRODUCT находится название любимого блюда.
+-------------------+
|        FOOD       |
+-------------------+
| USER_ID | PRODUCT |
+---------+---------+
| 1       | Сыр     |
+---------+---------+
| 2       | Молоко  |
+---------+---------+
Условимся что поле ID в таблице USERS и поле USER_ID в таблице FOOD являются первичными ключами (то есть имеют уникальные значения, которые не повторяются). Теперь попробуем использовать логику и найти любимое блюдо пользователя «Мышь», используя обе таблицы. Для этого мы сначала посмотрим в первую таблицу и найдём ID пользователя под именем «Мышь», а затем найдём название продукта под таким же ID во второй таблице. Объединяющие SQL запросы работают по такой же логике: нужен столбец, в по которому таблицы могут быть объединены.

Продемонстрируем запрос, объединяющий таблицы по столбцам ID и USER_ID:

SELECT * FROM `USERS` INNER JOIN `FOOD` ON `USERS`.`ID`=`FOOD`.`USER_ID`;
Разберём команду по словам. Начинается она как обычная выборка из одной таблицы со слов «SELECT * FROM USERS». Но затем идёт слово INNER, которое означает тип объединения. Существует три типа объединения таблиц: INNER, LEFT, RIGHT. Все они связаны с тем, что некоторым строкам в одной таблице может не найтись соответствующей строки во второй таблице. В таком случае при использовании «INNER» из результатов запроса будет удалены все строки, которым не нашлась соответствующая пара в другой таблице. Если же использовать вместо «INNER» слово «LEFT» или «RIGHT», то будут удалены строки, которые не нашли совпадение из первой (левой) или второй (правой) таблицы.

После слова «INNER» стоит слово «JOIN» (которое переводится с английского как «ПРИСОЕДИНИТЬ»). После слова «JOIN» стоит название таблицы, которая будет присоединена. В нашем случае это таблица FOOD. После названия таблицы стоит слово «ON» и равенство USERS.ID=FOOD.USER_ID, которое задаёт правило присоединения. При выполнении выборки будут объединены две таблицы так, чтобы значения в столбце ID таблицы USERS равнялось значению USER_ID таблицы FOOD.

В результате выполнения этого SQL запроса мы получим таблицу с четырьмя столбцами:

+----+------+---------+---------+
| ID | NAME | USER_ID | PRODUCT |
+----+------+---------+---------+
| 1  | Мышь | 1       | Сыр     |
+----+------+---------+---------+
| 2  | Кот  | 2       | Молоко  |
+----+------+---------+---------+
Предлагаем модифицировать запрос, потому что нам не нужны все четыре столбца. Уберём столбцы ID и USER_ID. Для этого вместо * в команде SELECT поставим название столбцов. Но необходимо сделать это, ставя сначала название таблицы и через точку название столбца. Чтобы получилось так:
SELECT `USERS`.`NAME`, `FOOD`.`PRODUCT` 
FROM `USERS` INNER JOIN `FOOD` ON `USERS`.`ID`=`FOOD`.`USER_ID`;
Теперь результат будет компактнее. И благодаря уменьшенному количеству запрашиваемых данных, результат будет получаться из базы быстрее:
+------+---------+
| NAME | PRODUCT |
+------+---------+
| Мышь | Сыр     |
+------+---------+
| Кот  | Молоко  |
+------+---------+

Если в двух таблицах имеются столбцы с одинаковыми названиями, то будет показан только последний столбце с таким названием. Чтобы этого не происходило, выбирайте определённый столбцы и используйте команду «AS» с помощью которой можно переименовать столбец в результатах выборки.

Давайте теперь решим логическую задачу, которую поставили в начале статьи. Попробуем выбрать в этой объединённой таблице только одну строку, которая соответствует пользователю «Мышь». Для этого используем условие WHERE в SQL запросе:
SELECT `USERS`.`NAME`, `FOOD`.`PRODUCT` 
FROM `USERS` INNER JOIN `FOOD` ON `USERS`.`ID`=`FOOD`.`USER_ID`
WHERE `USERS`.`NAME` LIKE 'Мышь';
Обратите внимание, что в условии WHERE название полей так же необходимо ставить вместе с названием таблицы через точку: USERS.NAME. В результате выполнения этого запроса появится такой результат:
+------+---------+
| NAME | PRODUCT |
+------+---------+
| Мышь | Сыр     |
+------+---------+
Отлично! Теперь мы знаем, как делать объединение таблиц.

sql — ПРИСОЕДИНЯЙТЕСЬ к двум результатам оператора SELECT

Можно ли объединить результаты 2 операторов sql SELECT в один оператор? У меня есть база данных задач, где каждая запись представляет собой отдельную задачу с крайними сроками (и PALT , что составляет всего INT дней от начала до крайнего срока. Age также равно INT дней. )

Я хочу иметь таблицу, в которой есть каждый человек в таблице, количество задач, которые у них есть, и количество ПОЗДНИХ задач, которые у них есть (если есть.)

Я могу легко получить эти данные в отдельных таблицах, например:

  ВЫБРАТЬ ks, COUNT (*) AS '# Tasks' FROM Table GROUP BY ks
  

возвращает такие данные, как:

  ks # Задачи
person1 7
человек2 3
  

а потом у меня:

  SELECT ks, COUNT (*) AS '# Late' FROM Table WHERE Age> Palt GROUP BY ks
  

, который возвращает:

  ks # Поздно
person1 1
person2 1
  

И я хочу объединить результаты этих двух операторов select (по KS )

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

Я также попытался сделать что-то вроде count () строк, которые удовлетворяют условию, но я тоже не мог понять, как это сделать. Если возможно, это тоже сработает.

Приложение: Извините, я хочу, чтобы в моих результатах были столбцы для KS , Tasks и Late

  KS # Задачи # Поздно
person1 7 1
человек2 3 1
person3 2 0 (или ноль)
  

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

SUM (CASE WHEN Age> Palt THEN 1 ELSE 0 END) Поздний
работает хорошо, спасибо за этот ответ!

Два оператора select также работают, использование LEFT JOIN для их соединения также работает, и теперь я понимаю, как объединить несколько select таким образом

mysql — объединение двух операторов выбора

Кто-нибудь может сказать мне, почему следующее не работает? Он жалуется на синтаксическую ошибку рядом с ключевым словом соединения между двумя выборками.

  ВЫБРАТЬ *
ОТ (выберите * из orders_products внутренних заказов JOIN ON orders_products.orders_id = orders.orders_id, где products_id = 181)
как

присоединиться

ВЫБРАТЬ *
ОТ (выберите * из orders_products INNER JOIN orders ON orders_products.orders_id = orders.orders_id, где products_id = 180)
как B

на A.orders_id = B.orders_id
  

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

Теперь у меня

 _______A_________ _______B_________ 
O_ID P_ID Q O_ID P_ID Q
1180 3 1181 11
2180 9 2181 6
3180 5 3181 3

И, используя другое соединение, я хочу получить

 
Q_ID P_ID1 Q1 P_ID2 Q2
1 180 3 181 11
2 180 9 181 6
3 180 5 181 3

Может, я здесь ошибаюсь.Какие-либо предложения?

ОБНОВЛЕНИЕ: Вот что у меня сработало после указателей RedFilter:

  (ВЫБРАТЬ *
ИЗ (
ВЫБРАТЬ * ИЗ orders_products
INNER JOIN заказы ON orders_products.orders_id = orders.orders_id
ГДЕ products_id = 181) КАК A
LEFT JOIN (
ВЫБРАТЬ * ИЗ orders_products
INNER JOIN заказы ON orders_products.orders_id = orders.orders_id
ГДЕ product_id = 180) AS B ON A.orders_id = B.orders_id
)
СОЮЗ (
ВЫБРАТЬ *
ИЗ (
ВЫБРАТЬ *
FROM orders_products
INNER JOIN заказы ON orders_products.orders_id = orders.orders_id
ГДЕ products_id = 181
) Как C
ПРАВО ПРИСОЕДИНИТЬСЯ (
ВЫБРАТЬ *
FROM orders_products
INNER JOIN заказы ON orders_products.orders_id = orders.orders_id
ГДЕ products_id = 180
) AS D ON C.orders_id = D.orders_id
)
  

SQL присоединяется к


SQL JOIN

Предложение JOIN используется для объединения строк из двух или более таблиц на основе связанный столбец между ними.

Давайте посмотрим на выборку из таблицы «Заказы»:

Код заказа CustomerID Дата заказа
10308 2 1996-09-18
10309 37 1996-09-19
10310 77 1996-09-20

Затем посмотрите на выбор из таблицы «Клиенты»:

Идентификатор клиента CustomerName ContactName Страна
1 Альфредс Футтеркисте Мария Андерс Германия
2 Ana Trujillo Emparedados y helados Ана Трухильо Мексика
3 Антонио Морено Такерия Антонио Морено Мексика

Обратите внимание, что столбец «CustomerID» в таблице «Заказы» относится к «CustomerID» в таблице «Клиенты».Связь между двумя таблицами выше столбец «CustomerID».

Затем мы можем создать следующий оператор SQL (который содержит ВНУТРЕННЕЕ СОЕДИНЕНИЕ ), который выбирает записи, которые имеют совпадающие значения в обеих таблицах:

Пример

ВЫБЕРИТЕ Orders.OrderID, Customers.CustomerName, Orders.OrderDate
ИЗ Orders
ВНУТРЕННЕЕ ПРИСОЕДИНЯЙТЕСЬ к клиентам НА Orders.CustomerID = Customers.CustomerID;

Попробуй сам »

, и он выдаст что-то вроде этого:

Код заказа CustomerName Дата заказа
10308 Ana Trujillo Emparedados y helados 18.09.1996
10365 Антонио Морено Такерия 27.11.1996
10383 Вокруг Рога 16.12.1996
10355 Вокруг Рога 15.11.1996
10278 Berglunds snabbköp 12.08.1996

Различные типы SQL JOIN

Вот различные типы JOIN в SQL:

  • (INNER) JOIN : возвращает записи, которые имеют совпадающие значения в обеих таблицах
  • LEFT (OUTER) JOIN : возвращает все записи из левой таблицы и соответствующие записи из правой таблицы
  • RIGHT (OUTER) JOIN : возвращает все записи из правой таблицы и совпавших записи из левой таблицы
  • ПОЛНОЕ (ВНЕШНЕЕ) СОЕДИНЕНИЕ : возвращает все записи, если есть совпадение в любом из левых или правый стол




Пошаговое руководство по SQL Inner Join

Организации генерируют и анализируют непревзойденные объемы данных каждую минуту.В этой статье мы продемонстрируем, как мы можем использовать SQL Inner Join для запроса и доступа к данным из нескольких таблиц, которые хранят эти непрерывно растущие данные в базах данных SQL.

SQL объединяется

Прежде чем мы начнем с SQL Inner Join, я хотел бы вызвать здесь SQL Join. Присоединиться — это широко используемое предложение в SQL Server, по сути, для объединения и извлечения данных из двух или более таблиц. В реальной реляционной базе данных данные структурированы в виде большого количества таблиц, поэтому существует постоянная потребность в объединении этих нескольких таблиц на основе логических отношений между ними.В SQL Server существует четыре основных типа объединений — внутреннее, внешнее (левое, правое, полное), самостоятельное и перекрестное соединение. Чтобы получить быстрый обзор всех этих объединений, я бы порекомендовал пройти по этой ссылке, обзору типов соединений SQL и руководству.

Эта статья посвящена внутреннему соединению в SQL Server, так что давайте перейдем к ней.

Определение внутреннего соединения SQL

Предложение Inner Join в SQL Server создает новую таблицу (не физическую) путем объединения строк, имеющих совпадающие значения в двух или более таблицах.Это соединение основано на логической связи (или общем поле) между таблицами и используется для извлечения данных, которые появляются в обеих таблицах.

Предположим, у нас есть две таблицы, Таблица A и Таблица B, которые мы хотели бы объединить с помощью SQL Inner Join. Результатом этого соединения будет новый набор результатов, который возвращает совпадающие строки в обеих этих таблицах. В части пересечения, выделенной черным цветом ниже, показаны данные, полученные с помощью внутреннего соединения в SQL Server.

Синтаксис внутреннего соединения SQL Server

Ниже приведен базовый синтаксис Inner Join.

SELECT Column_list
FROM TABLE1
INNER JOIN TABLE2
ON Table1.ColName = Table2.ColName

Синтаксис внутреннего соединения в основном сравнивает строки таблицы 1 с таблицей 2, чтобы проверить, совпадает ли что-либо, на основе условия, указанного в предложении ON. Когда условие соединения выполнено, оно возвращает совпадающие строки в обеих таблицах с выбранными столбцами в предложении SELECT.

Предложение SQL Inner Join аналогично предложению Join и работает таким же образом, если мы не указываем тип (INNER) при использовании предложения Join.Короче говоря, Inner Join — это ключевое слово по умолчанию для Join, и оба могут использоваться взаимозаменяемо.

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

Внутреннее соединение SQL в действии

Давайте попробуем понять концепцию внутреннего соединения с помощью интересной выборки данных, касающейся пиццерии и ее распределения.Сначала я собираюсь создать две таблицы — таблицу PizzaCompany, которая управляет различными филиалами пиццерий в нескольких городах, и таблицу Foods, в которой хранятся данные о распределении продуктов питания в этих компаниях. Вы можете выполнить приведенный ниже код, чтобы создать и заполнить данные в этих двух таблицах. Все эти данные являются гипотетическими, и их можно создать в любой из существующих баз данных.

СОЗДАТЬ ТАБЛИЦУ [dbo]. [PizzaCompany]

(

[CompanyId] [int] IDENTITY (1,1) ПЕРВИЧНЫЙ КЛЮЧ КЛАСТЕРИРОВАН,

[CompanyName] [varchar] (50),

[CompanyCity] [ varchar] (30)

)

УСТАНОВИТЬ IDENTITY_INSERT [dbo].[PizzaCompany] ВКЛ;

ВСТАВИТЬ В [dbo]. [PizzaCompany] ([CompanyId], [CompanyName], [CompanyCity]) VALUES (1, ‘Dominos’, ‘Los Angeles’);

INSERT INTO [dbo]. [PizzaCompany] ([CompanyId], [CompanyName], [CompanyCity]) VALUES (2, «Pizza Hut», «Сан-Франциско»);

ВСТАВИТЬ В [dbo]. [PizzaCompany] ([CompanyId], [CompanyName], [CompanyCity]) VALUES (3, ‘Papa johns’, ‘San Diego’);

INSERT INTO [dbo]. [PizzaCompany] ([CompanyId], [CompanyName], [CompanyCity]) VALUES (4, ‘Ah Pizz’, ‘Fremont’);

ВСТАВИТЬ В [dbo].[PizzaCompany] ([CompanyId], [CompanyName], [CompanyCity]) ЗНАЧЕНИЯ (5, «Нино Пицца», «Лас-Вегас»);

ВСТАВИТЬ В [dbo]. [PizzaCompany] ([CompanyId], [CompanyName], [CompanyCity]) VALUES (6, ‘Пиццерия’, ‘Бостон’);

INSERT INTO [dbo]. [PizzaCompany] ([CompanyId], [CompanyName], [CompanyCity]) VALUES (7, ‘chuck e cheese’, ‘Chicago’);

ВЫБРАТЬ * ОТ PizzaКомпания:

Вот так выглядят данные в таблице PizzaCompany:

Давайте сейчас создадим и заполним таблицу Foods.CompanyID в этой таблице — это внешний ключ, который ссылается на первичный ключ таблицы PizzaCompany, созданной выше.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

17

18

СОЗДАТЬ ТАБЛИЦУ [dbo].[Foods]

(

[ItemId] INT ПЕРВИЧНЫЙ КЛЮЧ КЛАСТЕРИРОВАН,

[ItemName] Varchar (50),

[UnitsSold] int,

CompanyID int,

FOREIGN KEY (CompanyID) REFERENCES PizzaCompany (CompanyID)

)

INSERT INTO [dbo]. [Foods] ([ItemId], [ItemName], [UnitsSold], [CompanyId]) VALUES (1, ‘Large Pizza’, 5,2)

INSERT INTO [dbo » ]. [Продукты] ([ItemId], [ItemName], [UnitsSold], [CompanyId]) VALUES (2, ‘Garlic Knots’, 6,3)

ВСТАВИТЬ В [dbo].[Foods] ([ItemId], [ItemName], [UnitsSold], [CompanyId]) VALUES (3, ‘Large Pizza’, 3,3)

INSERT INTO [dbo]. [Foods] ([ItemId], [ ItemName], [UnitsSold], [CompanyId]) VALUES (4, ‘Средняя пицца’, 8,4)

INSERT INTO [dbo]. [Foods] ([ItemId], [ItemName], [UnitsSold], [CompanyId ]) VALUES (5, ‘Breadsticks’, 7,1)

INSERT INTO [dbo]. [Foods] ([ItemId], [ItemName], [UnitsSold], [CompanyId] »VALUES (6, ‘Medium Pizza’) , 11,1)

INSERT INTO [dbo]. [Foods] ([ItemId], [ItemName], [UnitsSold], [CompanyId]) VALUES (7, ‘Маленькая пицца’, 9,6)

INSERT INTO [dbo].[Еда] ([ItemId], [ItemName], [UnitsSold], [CompanyId]) ЗНАЧЕНИЯ (8, ‘Маленькая пицца’, 6,7)

ВЫБРАТЬ * ИЗ Foods

В следующей таблице показаны данные из таблицы «Продукты питания». В этой таблице хранится такая информация, как количество проданных единиц продукта питания, а также точка доставки пиццы (CompanyId), которая ее доставляет.

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

SELECT pz.CompanyCity, pz.CompanyName, pz.CompanyId AS PizzaCompanyId, f.CompanyID AS FoodsCompanyId, f.ItemName, f.UnitsSold

FROM PizzaCompany pz

INNER JOIN Foods f

ON p. CompanyId

Ниже приведен набор результатов указанного выше запроса SQL Inner Join. Для каждой строки в таблице PizzaCompany функция Inner Join сравнивает и находит совпадающие строки в таблице Foods и возвращает все совпадающие строки, как показано ниже.И если вы заметили, CompanyId = 5 исключается из результата запроса, так как он не соответствует в таблице Foods.

С помощью приведенного выше набора результатов мы можем различить товары, а также количество товаров, доставленных пиццериями в разных городах. Например, Dominos доставил в Лос-Анджелес 7 хлебных палочек и 11 средних пицц.

Внутреннее соединение SQL трех таблиц

Давайте подробнее рассмотрим это объединение и предположим, что в штате открываются три аквапарка (похоже, летом), и эти аквапарки передают еду на аутсорсинг в пиццерии, упомянутые в таблице PizzaCompany.

Я собираюсь быстро создать таблицу WaterPark и загрузить в нее произвольные данные, как показано ниже.

СОЗДАТЬ ТАБЛИЦУ [dbo]. [WaterPark]

(

[WaterParkLocation] VARCHAR (50),

[CompanyId] int,

ИНОСТРАННЫЙ КЛЮЧ (CompanyID) ССЫЛКИ PizzaCompany (CompanyID)

IN)

IN [dbo]. [WaterPark] ([WaterParkLocation], [CompanyId]) ЗНАЧЕНИЯ (‘Улица 14’, 1)

ВСТАВИТЬ В [dbo].[WaterPark] ([WaterParkLocation], [CompanyId]) ЗНАЧЕНИЯ (‘Boulevard 2’, 2)

ВСТАВИТЬ [dbo]. [WaterPark] ([WaterParkLocation], [CompanyId]) ЗНАЧЕНИЯ (‘Rogers 54’, 4)

ВСТАВИТЬ В [dbo]. [WaterPark] ([WaterParkLocation], [CompanyId]) ЗНАЧЕНИЯ (‘Street 14’, 3)

ВСТАВИТЬ В [dbo]. [WaterPark] ([WaterParkLocation], [CompanyId]) ЗНАЧЕНИЯ (‘Rogers 54’, 5)

ВСТАВИТЬ В [dbo]. [WaterPark] ([WaterParkLocation], [CompanyId]) ЗНАЧЕНИЯ (‘Boulevard 2’, 5)

ВЫБРАТЬ * ИЗ WaterPark

И ниже вывод этой таблицы.

Как говорится, картина стоит тысячи слов. Давайте быстро посмотрим на схему базы данных этих трех таблиц с их взаимосвязями, чтобы лучше понять их.

Теперь мы собираемся включить эту третью таблицу в предложение SQL Inner Join, чтобы увидеть, как это повлияет на набор результатов. Согласно данным в таблице «Аквапарк», три аквапарка передают еду на аутсорсинг всем пиццериям, кроме пиццерии (Id = 6) и Chuck e Cheese (Id = 7).Выполните приведенный ниже код, чтобы увидеть, как распределяется еда в аквапарках у точек Pizza.

ВЫБРАТЬ pz.CompanyId, pz.CompanyCity, pz.CompanyName, f.ItemName, f.UnitsSold,

w.WaterParkLocation

FROM PizzaCompany pz

INNER JOIN Foods company f ON pz.ComId13 ПРИСОЕДИНЯЙТЕСЬ к аквапарку w.CompanyId = pz.CompanyId

ЗАКАЗАТЬ pz.CompanyId

На основе CompanyId SQL Inner Join сопоставляет строки в обеих таблицах, PizzaCompany (Таблица 1) и Foods (Таблица 2), а затем ищет совпадение в WaterPark (Таблица 3), чтобы вернуть строки.Как показано ниже, с добавлением внутреннего соединения в WaterPark, CompanyId (6,7 (кроме 5)) также исключается из окончательного набора результатов, поскольку условие w.CompanyId = pz.CompanyId не выполняется для идентификаторов (6, 7). Вот как внутреннее соединение SQL помогает возвращать определенные строки данных из нескольких таблиц.

Давайте углубимся в SQL Inner Join, добавив еще несколько предложений T-SQL.

Использование WHERE с внутренним соединением

Мы можем фильтровать записи на основе указанного условия, когда внутреннее соединение SQL используется с предложением WHERE.Предположим, мы хотели бы получить строки, в которых проданных единиц было больше 6.

В следующем запросе предложение WHERE добавляется для извлечения результатов со значением более 6 для проданных единиц.

SELECT pz.CompanyId, pz.CompanyCity, pz.CompanyName, f.ItemName, f.UnitsSold

FROM PizzaCompany pz

INNER JOIN Foods f ON pz.CompanyId = f.CompanyId

WHERE f.Units

ЗАКАЗАТЬ pz.КомпанияГород

Выполните приведенный выше код в SSMS, чтобы увидеть результат ниже. Этот запрос возвращает четыре таких записи.

Использование Group By с внутренним соединением

SQL Inner Join позволяет нам использовать предложение Group by вместе с агрегатными функциями для группировки набора результатов по одному или нескольким столбцам. Группировка по обычно работает с внутренним объединением по окончательному результату, возвращаемому после объединения двух или более таблиц. Если вы не знакомы с предложением Group by в SQL, я бы посоветовал пройти через это, чтобы быстро понять эту концепцию.Ниже приведен код, в котором используется предложение Group By с внутренним соединением.

SELECT pz.CompanyCity, pz.CompanyName, SUM (f.UnitsSold) AS TotalQuantitySold

FROM PizzaCompany pz

INNER JOIN Foods f ON pz.CompanyId = f.CompanyId

GROUP BY pz.CompanyCity, pz.CompanyCity, pz.CompanyCity

ЗАКАЗАТЬ pz.CompanyCity

Здесь мы собираемся получить общее количество товаров, проданных каждой пиццерией, присутствующей в городе.Как видно ниже, агрегированный результат в столбце «totalquantitysold» равен 18 (7 + 11) и 9 (6 + 3) для Лос-Анджелеса и Сан-Диего соответственно.

Краткое описание Equi и Theta Join

Прежде чем мы закончим эту статью, давайте быстро рассмотрим термины, которые разработчик SQL может время от времени слышать — Equi и Theta Join.

Equi Join

Как следует из названия, equi join содержит оператор равенства ‘=’ либо в предложении Join, либо в условии WHERE.SQL Inner, Left, Right — все равнозначные соединения, когда оператор «=» используется в качестве оператора сравнения. Обычно, когда упоминается внутреннее соединение SQL, оно рассматривается как внутреннее равное соединение, только в необычной ситуации оператор равенства не используется.

Чтобы упростить задачу, я собираюсь обратиться к образцу базы данных AdventureWorksDW2017 и запустить запрос к существующим таблицам, чтобы продемонстрировать, как выглядит равное соединение.

ВЫБРАТЬ e.EmployeeKey, e.FirstName, e.Title, e.HireDate,

fs.SalesAmountQuota ОТ DimEmployee e

ВНУТРЕННЕЕ СОЕДИНЕНИЕ FactSalesQuota fs

НА e.EmployeeKey = fs.EmployeeKey

901

Theta Join (Неравномерное соединение)

Неравномерное соединение в основном противоположно равнозначному соединению и используется, когда мы соединяемся с условием, отличным от оператора «=». На практике этот тип используется редко. Ниже приведен пример, в котором используется тета-соединение с оператором неравенства (<) для оценки прибыли путем оценки себестоимости и продажных цен в двух таблицах.

ВЫБРАТЬ * ИЗ Таблица1 T1, Таблица2 T2 ГДЕ T1.ProductCost

Заключение

Я надеюсь, что эта статья о «Внутреннем соединении SQL» обеспечивает понятный подход к одному из важных и часто используемых предложений — «Внутреннее соединение» в SQL Server для объединения нескольких таблиц. Если у вас есть какие-либо вопросы, не стесняйтесь задавать их в разделе комментариев ниже.

Чтобы продолжить изучение SQL-соединений, вы можете обратиться к сообщениям ниже:

Гаури является специалистом по SQL Server и имеет более 6 лет опыта работы с международными международными консалтинговыми и технологическими организациями. Она очень увлечена работой над такими темами SQL Server, как База данных SQL Azure, Службы отчетов SQL Server, R, Python, Power BI, ядро ​​базы данных и т. Д. Она имеет многолетний опыт работы с технической документацией и увлекается разработкой технологий.

Она имеет большой опыт в разработке решений для данных и аналитики, а также в обеспечении их стабильности, надежности и производительности. Она также сертифицирована по SQL Server и прошла такие сертификаты, как 70-463: Внедрение хранилищ данных с Microsoft SQL Server.

Посмотреть все сообщения от Gauri Mahajan

Последние сообщения от Gauri Mahajan (посмотреть все)

Введение и обзор предложения SQL Join

Предложение SQL Join — один из основных компонентов оператора Select, который используется для извлечения данных из SQL Server.

Ключевое слово Select запускает оператор.За ним часто следует звездочка (*) AKA splat, как называют это некоторые администраторы баз данных.

Примечание. Для автоматического расширения подстановочных знаков в явные столбцы см. Как предотвратить проблемы с производительностью и ошибки из-за подстановочных знаков в операторах SELECT

Это просто означает возврат всех столбцов. Если у нас есть несколько таблиц, звездочка Select будет захватывать все столбцы из всех таблиц, например, при объединении нескольких таблиц вместе с помощью предложения SQL Join, которое является основной темой этой статьи.

Начнем с определения. Присоединение — это процесс взятия данных из нескольких таблиц и помещения их в одно сгенерированное представление. Таким образом, предложение SQL Join в операторе Select объединяет столбцы из одной или нескольких таблиц в реляционной базе данных и возвращает набор данных.

From также является важной частью оператора Select, и именно здесь указывается, из какой таблицы мы извлекаем данные. Часть соединения — это если мы хотим вывести данные из нескольких таблиц и у нас есть три разных типа соединений:

  • Внутреннее соединение — это значение по умолчанию.Если мы не укажем тип соединения, он будет использоваться по умолчанию как внутреннее соединение. Это означает, что если мы объединяем две таблицы в общем столбце, возвращаем только те данные, которые совпадают в обеих таблицах.

  • Левое соединение — этот тип соединения означает, что возвращаются все данные в левой таблице и только те данные, которые соответствуют левой таблице в правой таблице

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

Выбрать с помощью внутреннего соединения

Давайте перейдем к SQL Server Management Studio (SSMS) и посмотрим, как мы можем работать с предложением SQL Join на реальных примерах. Ниже приведен пример объединения таблиц в общий столбец. В нашем примере базы данных AdventureWorks2012 у нас есть таблица «Продукт» со столбцом «ProductID», а в таблице «SalesOrderDetail» также есть столбец «ProductID».Итак, если мы хотим узнать общие продажи и скидки для каждого продукта и вытащить название, мы должны объединить эти два вместе в этом общем столбце:

ЕГЭ AdventureWorks2012;

GO

ВЫБЕРИТЕ p.Name AS ProductName,

NonDiscountSales = (OrderQty * UnitPrice),

Скидки = ((OrderQty * UnitPrice) * UnitPriceDiscount)

FROM Production.Product AS p

JO.SalesOrderDetail AS sod

НА p.ProductID = sod.ProductID

ORDER BY ProductName DESC;

ГО

Обратите внимание, что если вы просто укажете Join, без ключевого слова Inner в предложении SQL Join, оно все равно будет внутренним соединением. Вы, конечно, можете указать ключевое слово Inner для ясности, но если нет соединения левого / правого тега, по умолчанию оно будет просто внутренним соединением:

Выбрать с помощью левого соединения

Теперь давайте посмотрим на левое внешнее соединение, которое дает нам все из левой таблицы и только записи, соответствующие в правой таблице.В нашем примере запрос ниже предоставит нам людей, которые не совершали покупок:

ВЫБЕРИТЕ *

ОТ Person.Person p

ЛЕВЫЙ ПРИСОЕДИНИТЬСЯ к Sales.PersonCreditCard pcc ON p.BusinessEntityID = pcc.BusinessEntityID

Левое соединение возвращает все записи, даже если они не существуют, и помещает значение Null, если оно не существует:

Набор результатов показывает, что было возвращено 19972 записи, и у нас есть группа Nulls в столбце BusinessEntityID.Строки с пустыми значениями — это люди, которые не совершали покупок.

Мы можем расширить приведенный выше запрос и добавить еще одно предложение SQL Join, чтобы включить людей с информацией о кредитной карте. Обратите внимание, что мы только что указали ключевое слово Join, которое по умолчанию является внутренним объединением, и оно удалит все пустые значения, потому что у этих людей нет информации о кредитной карте:

ВЫБРАТЬ *

ОТ ЛИЦА.Человек p

ЛЕВЫЙ ПРИСОЕДИНЯЙТЕСЬ к Sales.PersonCreditCard pcc ON p.BusinessEntityID = pcc.BusinessEntityID

ПРИСОЕДИНЯЙТЕСЬ к Sales.CreditCard cc НА pcc.CreditCardID = cc.CreditCardID;

На этот раз запрос возвращает 19118 записей вместо предыдущих 19972:

Вот как нам может помочь соединение SQL с тегом Left. Если мы хотим включить записи и получить полное количество людей, даже если они не совершали покупок, просто оставьте присоединиться ко второму предложению:

ВЫБРАТЬ *

ОТ ЛИЦА.Человек p

ЛЕВЫЙ ПРИСОЕДИНЯЙТЕСЬ к Sales.PersonCreditCard pcc ON p.BusinessEntityID = pcc.BusinessEntityID

ЛЕВЫЙ ПРИСОЕДИНЯЙТЕСЬ к Sales.CreditCard cc ON pcc.CreditCardID = cc.CreditCardID;

Мы видим, что у всех, кто не совершал покупки, есть пустая запись для таблиц «CreditCard» и «PersonCreditCard» с тех пор, как мы покинули их:

Кроме того, мы можем выделить всех тех людей, которые еще не совершили покупку, расширив предложение SQL Join еще больше и выполнив поиск значений Null с помощью предложения Where:

ВЫБРАТЬ *

ОТ ЛИЦА.Человек p

ЛЕВЫЙ ПРИСОЕДИНЯЙТЕСЬ к Sales.PersonCreditCard pcc ON p.BusinessEntityID = pcc.BusinessEntityID

ЛЕВЫЙ СОЕДИНЯЙТЕСЬ Sales.CreditCard cc ON pcc.CreditCardID = cc.CreditCardID

ГДЕ pcc.BusinessEntityID IS NULL;

Если мы запустим это, мы получим 854 записи или, как упоминалось выше, всех, кто не совершил покупку:

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

Выбрать с помощью правого соединения

Теперь предложение SQL Join с правым соединением является полной противоположностью левого соединения. По сути, они делают то же самое. Слева — справа, а справа — слева, и тот же эффект можно получить, просто перевернув таблицы. Правильные соединения никоим образом не являются устаревшими, просто они не слишком распространены. Для единообразия обычной практикой является использование левых соединений вместо правых.

Заключение и общие практики

Мы рассмотрели три основных соединения: внутреннее, левое и правое соединение. Именно эти три используются наиболее широко. И даже если вы новичок в мире баз данных, весьма вероятно, что вы довольно часто встречали различные типы SQL-соединений.

В дополнение к этому вы также увидите типы объединений Внешний и Перекрестный. Внешнее соединение имеет 3 разных типа:

  1. Левое внешнее соединение — извлекает записи, если они есть в левой таблице
  2. Правое внешнее соединение — извлекает записи, если они есть в правой таблице
  3. Полное внешнее соединение — извлекает записи, если они есть в любой из двух таблиц

  1. Cross join — как следует из названия, делает [n X m], который соединяет все со всем.Как в сценарии, где мы просто перечисляем таблицы для объединения (в предложении From оператора Select), разделяя их запятыми.

На заметку:

  • Если вы просто укажете соединение, то по умолчанию это внутреннее соединение.
  • Внешнее соединение должно быть левым / правым / полным. Вы не можете просто сказать «Внешнее присоединение» и оставить это здесь.
  • Вы можете отбросить ключевое слово Outer и просто сказать Left join, Right join или Full join.

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

Я надеюсь, что эта статья была для вас информативной, и благодарю вас за то, что вы ее прочитали.


Боян, он же «Бокси», выпускник AP в области ИТ-технологий, специализирующийся на сетях и электронных технологиях Копенгагенской школы дизайна и технологий, является аналитиком программного обеспечения с опытом в области обеспечения качества, поддержки программного обеспечения, пропаганды продуктов и взаимодействия с пользователями.

Он много писал о SQL Shack и ApexSQL Solution Center по самым разным темам, от клиентских технологий, таких как разрешение 4K и тематика, обработки ошибок до стратегий индексации и мониторинга производительности.

Боян работает в ApexSQL в Нише, Сербия, как неотъемлемая часть команды, занимающейся проектированием, разработкой и тестированием следующего поколения инструментов баз данных, включая MySQL и SQL Server, а также автономных инструментов и интеграции с Visual Studio, SSMS. и VSCode.

См. Больше о Бояне на LinkedIn

Просмотреть все сообщения Боян Петрович

Последние сообщения Боян Петрович (посмотреть все)

SQL JOIN, JOIN Syntax, JOIN Differences, 3 таблицы — с примерами

Как получить данные из нескольких таблиц?

SQL JOIN объединяет записи из двух таблиц.
JOIN находит связанные значения столбцов в двух таблицах.
Запрос может содержать ноль, одну или несколько операций JOIN.
INNER JOIN — это то же самое, что и JOIN; ключевое слово INNER необязательно.


Четыре разных типа JOIN

  1. (INNER) JOIN: выберите записи, которые имеют совпадающие значения в обеих таблицах.
  2. ПОЛНОЕ (ВНЕШНЕЕ) СОЕДИНЕНИЕ: выбирает все записи, соответствующие либо левой, либо правой записям таблицы.
  3. LEFT (OUTER) JOIN: выберите записи из первой (самой левой) таблицы с соответствующими записями правой таблицы.
  4. RIGHT (OUTER) JOIN: выберите записи из второй (самой правой) таблицы с соответствующими записями левой таблицы.

Примечание. Все ключевые слова INNER и OUTER необязательны.
Подробности о различных соединениях доступны на следующих страницах руководства.

Синтаксис SQL JOIN

Общий синтаксис

ВЫБЕРИТЕ имена столбцов
  FROM table-name1 ПРИСОЕДИНЯТЬСЯ к table-name2
    ON имя-столбца1 = имя-столбца2
 ГДЕ условие
 

Общий синтаксис INNER:
ВЫБЕРИТЕ имена столбцов
  ИЗ имя-таблицы1 ВНУТРЕННЕЕ СОЕДИНЕНИЕ имя-таблицы2
    ON имя-столбца1 = имя-столбца2
 ГДЕ условие
 

Примечание. Ключевое слово INNER является необязательным: оно используется по умолчанию, а также является наиболее часто используемой операцией JOIN.
9013 9013 901 901 901 901 901 901 901 901 901 901 901 901 901 9013 Дата заказа
ЗАКАЗЧИК
Идентификатор
Имя
Фамилия
Город
Страна
Номер заказа
CustomerId
TotalAmount

Примеры SQL JOIN

Проблема: Список всех заказов с информацией о покупателе

ВЫБЕРИТЕ 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 Ян Ван Берн Швейцария

ПРОДУКТ
Id
ProductName
SupplierID
UnitPrice
Комплект
IsDiscontinued
OrderItem
Id
OrderId
PRODUCTID
UnitPrice
Количество
ПРИКАЗ
Id
OrderDate
ORDERNUMBER
CustomerId
TotalAmount

Задача: Список всех заказов
с названиями продуктов,
количества и цены

ВЫБЕРИТЕ 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
 

Результат: 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 Луизиана Fiery Hot Pepper Sauce 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 Луизиана Fiery Hot Pepper Sauce 20 16,80
542382 09.07.2012 00:00:00 Мармелад сэра Родни 40 64,80
542382 9.07.2012 00:00:00 Гейтост 25 2.00

sql — множественный SELECT с LEFT JOIN для упорядочивания результатов

У меня есть две таблицы, которые выглядят так:

Таблица 1

  id | имя | Дата
--- + ------ + ---------------------
 1 | заак | 2016-08-03 11:37:40 - топ-1 дат, имя # 5
 2 | аап | 2016-08-01 11:40:35
 3 | кукуруза | 2016-08-02 11:42:16 - топ-3 даты, имя # 3
 4 | кварт | 2016-08-02 11:42:28 - топ-2 даты, имя # 4
 5 | альфа | 2016-07-04 11:44:29
  

Таблица 2

  id | открыть | имя | name_id | тип
--- + ------ + ------- + --------- + -----
 1 | 1 | аап | 2 | 2 - тип = 2, открытый = 1: 1
 2 | 1 | кварт | 4 | 2 - тип = 2, открытый = 1: 1
 3 | 1 | кварт | 4 | 2 - тип = 2, открытый = 1: 1
 4 | 1 | динки | 1 | 1 - тип = 1, открытый = 1: NULL
 5 | 2 | кварт | 1 | 1 - тип = 1, открытый = 2: NULL
  

Мне нужен результат id и name из таблицы 1 и open из таблицы 2.

Требования:

  • из таблицы 1: выберите три последних по дате
  • заказать эти три по имя от A до Z
  • из таблицы 2: выберите открыть
    • IF name not there return NULL
    • IF тип <> 2 возврат NULL
    • IF open <> 1 return NULL
    • ELSE возврат 1

Путем проб и ошибок я построил этот запрос:

  - получить идентификатор, имя и открыть только один раз
ВЫБРАТЬ ОТЛИЧИТЕЛЬНЫЙ t1.id, t1.name, t3.open  - выберите имена из таблицы 1, отсортируйте их по дате и верните первые 3
FROM (SELECT id, name FROM table1 ORDER BY date DESC LIMIT 3) КАК t1  - открыть из таблицы 2, ЕСЛИ там есть id, open = 1 и type = 2
LEFT JOIN ((ВЫБРАТЬ open, name_id
 ИЗ table2
 ГДЕ открыть = 1 И тип = 2
 ) AS t3
 )
ВКЛ t1.id = t3.