INNER JOIN. Внутреннее объединение таблиц в MySQL

Команда INNER JOIN

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

Диаграмма выбора данных из таблиц через INNER JOIN
Диаграмма выбора данных из таблиц через INNER JOIN

Синтаксис INNER JOIN

mysql> SELECT column1, column2, ... , columnN
    -> FROM table1
    -> INNER JOIN table2 ON table1.column = table2.column;

Например, у нас есть база данных книжного магазина Bookstore и ее связанные таблицы customers и orders. Выведем их содержимое и увидим, что колонка customer_id в таблице orders, использует значения, которые полностью совпадают со значениями колонки id в таблице customers.

mysql> SELECT id, first_name, last_name 
    -> FROM customers;
+----+----------------+----------------+
| id | first_name     | last_name      |
+----+----------------+----------------+
|  1 | Олег           | Пальшин        |
|  2 | Jane           | Doherty        |
|  3 | Евгений        | Серов          |
|  4 | София          | Молина         |
|  5 | John           | Doe            |
+----+----------------+----------------+
5 rows in set (0.00 sec)

mysql> SELECT id, customer_id, employer_id, status, order_date
    -> FROM orders;
+----+-------------+-------------+------------------+---------------------+
| id | customer_id | employer_id | status           | order_date          |
+----+-------------+-------------+------------------+---------------------+
|  3 |           1 |           3 | Готов к отправке | 2019-01-05 04:55:58 |
|  6 |           3 |           3 | Готов к отправке | 2019-01-15 14:56:12 |
|  7 |           2 |           2 | Завершен         | 2019-01-11 20:59:40 |
|  9 |           4 |           3 | Обрабатывается   | 2018-12-22 21:16:16 |
| 10 |           2 |           3 | Готов к отправке | 2018-12-24 04:28:54 |
+----+-------------+-------------+------------------+---------------------+
5 rows in set (0.00 sec)

Теперь, зная что у нас есть совпадения значений колонок customers.id и orders.customer_id выполним их сведение, в котором подставим имя и фамилию клиента вместо его идентификатора.

mysql> SELECT orders.id, customers.first_name, customers.last_name, orders.status, orders.order_date
    -> FROM orders
    -> INNER JOIN customers ON orders.customer_id = customers.id;
+----+------------+-----------+------------------+---------------------+
| id | first_name | last_name | status           | order_date          |
+----+------------+-----------+------------------+---------------------+
|  3 | Олег       | Пальшин   | Готов к отправке | 2019-01-05 04:55:58 |
|  6 | Евгений    | Серов     | Готов к отправке | 2019-01-15 14:56:12 |
|  7 | Jane       | Doherty   | Завершен         | 2019-01-11 20:59:40 |
|  9 | София      | Молина    | Обрабатывается   | 2018-12-22 21:16:16 |
| 10 | Jane       | Doherty   | Готов к отправке | 2018-12-24 04:28:54 |
+----+------------+-----------+------------------+---------------------+

Внутреннее объединение для более двух таблиц

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

К таблицам customers и orders добавим еще одну таблицу employers, в которой хранятся записи о сотрудниках интернет магазина.

mysql> SELECT id, first_name, last_name, position FROM employers;
+----+------------+----------- +-------------------+
| id | first_name | last_name  | position          |
+----+------------+----------- +-------------------+
|  1 | Абросим    | Сумароков  | Ген. Директор     |
|  2 | Александр  | Суматохин  | Старший продавец  |
|  3 | Петр       | Стропин    | Продавец          |
|  4 | Фёдор      | Телецкий   | Кладовщик         |
+----+------------+----------- +-------------------+
4 rows in set (0.00 sec)

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

mysql> SELECT orders.id, CONCAT(customers.first_name, ' ', customers.last_name) AS 'Имя клиента',
    -> CONCAT(employers.first_name, ' ', employers.last_name, ' (', employers.position, ')') AS 'Заказ принял',
    -> orders.status, orders.order_date
    -> FROM ((orders
    -> INNER JOIN customers ON orders.customer_id = customers.id)
    -> INNER JOIN employers ON orders.employer_id = employers.id) ORDER BY id;
+----+---------------+----------------------------------------+-------------------+---------------------+
| id | Имя клиента   | Заказ принял                           | status            | order_date          |
+----+---------------+----------------------------------------+-------------------+---------------------+
|  3 | Олег Пальшин  | Петр Стропин (Продавец)                | Готов к отправке  | 2019-01-05 04:55:58 |
|  6 | Евгений Серов | Александр Суматохин (Старший продавец) | Готов к отправке  | 2019-01-15 14:56:12 |
|  7 | Jane Doherty  | Александр Суматохин (Старший продавец) | Завершен          | 2019-01-11 20:59:40 |
|  9 | София Молина  | Петр Стропин (Продавец)                | Обрабатывается    | 2018-12-22 21:16:16 |
| 10 | Jane Doherty  | Петр Стропин (Продавец)                | Готов к отправке  | 2018-12-24 04:28:54 |
+----+---------------+----------------------------------------+-------------------+---------------------+
5 rows in set (0.00 sec)

Разница между INNER JOIN и WHERE

Для внутреннего объединения таблиц можно также воспользоваться оператором WHERE.

Выведем объединение таблиц customers и orders из первого примера, но теперь вместо INNER JOIN будем использовать оператор WHERE.

mysql> SELECT orders.id, customers.first_name, customers.last_name, orders.status, orders.order_date
    -> FROM customers, orders
    -> WHERE customers.id = orders.customer_id;
+----+------------+-----------+------------------+---------------------+
| id | first_name | last_name | status           | order_date          |
+----+------------+-----------+------------------+---------------------+
|  3 | Олег       | Пальшин   | Готов к отправке | 2019-01-05 04:55:58 |
|  6 | Евгений    | Серов     | Готов к отправке | 2019-01-15 14:56:12 |
|  7 | Jane       | Doherty   | Завершен         | 2019-01-11 20:59:40 |
|  9 | София      | Молина    | Обрабатывается   | 2018-12-22 21:16:16 |
| 10 | Jane       | Doherty   | Готов к отправке | 2018-12-24 04:28:54 |
+----+------------+-----------+------------------+---------------------+
5 rows in set (0.00 sec)

Как видим в результатах вывода, по сравнению с первым примером, нет никакой разницы.

В плане производительности особых различий также не наблюдается.

Использовать INNER JOIN или WHERE для создания внутреннего объединения таблиц, решать вам. Тем не менее многие считают, что INNER JOIN будет гораздо логичнее и более читабельнее по сравнению с WHERE