Введение в JOIN: что это, зачем нужен, базовый синтаксис и типы соединений
JOIN — это операция, которая позволяет комбинировать данные из нескольких таблиц на основе связанных колонок. Без JOIN вам пришлось бы выполнять множество отдельных запросов и объединять результаты в коде приложения.
Представьте, что у вас есть две таблицы: users (пользователи) и orders (заказы). Информация о пользователе хранится отдельно от его заказов. Чтобы получить список заказов с именами пользователей, вам нужно объединить эти таблицы.
Без JOIN (плохой подход — N+1 запрос):
-- Сначала получаем все заказы
SELECT * FROM orders;
-- Затем для каждого заказа делаем отдельный запрос к users
SELECT name FROM users WHERE id = 1;
SELECT name FROM users WHERE id = 2;
-- ... и так далееС JOIN (один запрос):
SELECT users.name, orders.product, orders.amount
FROM users
JOIN orders ON users.id = orders.user_id;SELECT <колонки>
FROM <таблица1>
JOIN <таблица2> ON <условие_соединения>;Ключевые компоненты:
FROM — указывает основную таблицу (левую)JOIN — указывает таблицу для соединения (правую)ON — определяет условие, по которому строки считаются связаннымиСоздадим тестовые таблицы для примеров:
-- Таблица пользователей
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE
);
-- Таблица заказов
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
product VARCHAR(100),
amount DECIMAL(10, 2)
);
-- Добавим данные
INSERT INTO users (name, email) VALUES
('Alice', 'alice@example.com'),
('Bob', 'bob@example.com'),
('Charlie', 'charlie@example.com');
INSERT INTO orders (user_id, product, amount) VALUES
(1, 'Laptop', 1200.00),
(1, 'Mouse', 50.00),
(2, 'Keyboard', 150.00);Данные в таблицах:
users:
+----+---------+---------------------+
| id | name | email |
+----+---------+---------------------+
| 1 | Alice | alice@example.com |
| 2 | Bob | bob@example.com |
| 3 | Charlie | charlie@example.com |
+----+---------+---------------------+
orders:
+----+---------+----------+--------+
| id | user_id | product | amount |
+----+---------+----------+--------+
| 1 | 1 | Laptop | 1200.00|
| 2 | 1 | Mouse | 50.00 |
| 3 | 2 | Keyboard | 150.00 |
+----+---------+----------+--------+
SELECT users.name, orders.product, orders.amount
FROM users
JOIN orders ON users.id = orders.user_id;Результат:
+-------+----------+--------+
| name | product | amount |
+-------+----------+--------+
| Alice | Laptop | 1200.00|
| Alice | Mouse | 50.00 |
| Bob | Keyboard | 150.00 |
+-------+----------+--------+
Обратите внимание:
SQL поддерживает несколько типов JOIN, каждый из которых возвращает разные наборы данных:
| Тип JOIN | Возвращает |
|---|---|
INNER JOIN | Только совпадающие строки из обеих таблиц |
LEFT JOIN | Все строки из левой таблицы + совпадения из правой |
RIGHT JOIN | Все строки из правой таблицы + совпадения из левой |
FULL JOIN | Все строки из обеих таблиц |
CROSS JOIN | Декартово произведение (все комбинации) |
Диаграмма Венна для визуализации:
INNER JOIN: LEFT JOIN: RIGHT JOIN: FULL JOIN:
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ A │ │ A │ │ │ │ A │
│ ∩ │ │ ● │ │ ● │ │ ● │
│ B │ │ B │ │ B │ │ B │
└─────┘ └─────┘ └─────┘ └─────┘
(пересечение) (левая + ∩) (правая + ∩) (объединение)
Примечание: В PostgreSQL ключевое слово
INNERможно опускать —JOINпо умолчанию означаетINNER JOIN.
Условие в ON определяет, какие строки считаются связанными. Чаще всего это сравнение по равенству:
-- Эквисоединение (equality join)
FROM users
JOIN orders ON users.id = orders.user_idНо можно использовать и другие операторы:
-- Неэксисоединение (nonequijoin)
FROM salaries
JOIN tax_brackets ON salaries.amount BETWEEN tax_brackets.min AND tax_brackets.maxДля удобства можно использовать псевдонимы:
SELECT u.name, o.product, o.amount
FROM users AS u
JOIN orders AS o ON u.id = o.user_id;Ключевое слово AS опционально для псевдонимов таблиц:
SELECT u.name, o.product
FROM users u
JOIN orders o ON u.id = o.user_id;JOIN позволяет соединять более двух таблиц:
SELECT u.name, o.product, p.category
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN products p ON o.product_id = p.id;Каждый новый JOIN добавляет ещё одну таблицу к запросу.
NULL в условии JOIN: NULL не равен NULL, поэтому строки с NULL в колонке соединения не совпадут.
Дубликаты: Если связь один-ко-многим, строки из левой таблицы могут дублироваться.
Производительность: Убедитесь, что колонки в условии ON проиндексированы (особенно внешние ключи).
Читаемость: Используйте псевдонимы и явный синтаксис JOIN ... ON вместо старого стиля WHERE.
FROM таблица1 JOIN таблица2 ON условиеON определяет, какие строки считаются связаннымиВ следующих темах мы подробно изучим каждый тип JOIN и продвинутые техники их использования.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.