Внешние соединения и JOIN с группировкой
Когда пары может не быть: внешние соединения
INNER JOIN выбрасывает строки без пары. Но иногда нужно сохранить все строки одной из таблиц, даже если совпадения нет. Для этого есть внешние соединения.
LEFT JOIN— все строки левой таблицы; если пары справа нет, столбцы правой будутNULL.RIGHT JOIN— зеркально: все строки правой таблицы.FULL JOIN— все строки обеих таблиц.
Пример: не у каждого самолёта в базе расписаны места. Чтобы увидеть все самолёты, в том числе без мест, берём LEFT JOIN и ищем те, где правая таблица пустая:
SELECT a.airplane_code, a.model
FROM airplanes a
LEFT JOIN seats s ON s.airplane_code = a.airplane_code
WHERE s.seat_no IS NULL; -- самолёты, у которых нет мест
JOIN + GROUP BY — самые полезные отчёты
Соединение часто сочетают с группировкой: «сколько маршрутов у каждой модели», «сколько мест каждого класса». Сначала JOIN собирает строки, затем GROUP BY группирует, и считается агрегат:
SELECT a.model, COUNT(*) AS routes
FROM routes r
JOIN airplanes a ON a.airplane_code = r.airplane_code
GROUP BY a.model
ORDER BY routes DESC;
Типичные ошибки
- Условие на правую таблицу в WHERE. В
airplanes a LEFT JOIN seats s … WHERE s.fare_conditions = 'Business'самолёты без мест пропадут: у нихs.fare_conditionsравенNULL, иWHEREих отбросит. Если такие строки нужны, условие переносят вON:LEFT JOIN seats s ON s.airplane_code = a.airplane_code AND s.fare_conditions = 'Business'. - COUNT(*) после LEFT JOIN. Для самолёта без мест
COUNT(*)даст 1 — он посчитает строку сNULL. Чтобы получить 0, считайте столбец правой таблицы:COUNT(s.seat_no). - Порядок таблиц в LEFT JOIN. Сохраняются строки той таблицы, что стоит слева.
seats LEFT JOIN airplanesиairplanes LEFT JOIN seats— разные запросы.
💡 Тонкость сLEFT JOIN:COUNT(*)считает все строки (даже с NULL от несостоявшейся пары), аCOUNT(s.seat_no)— только строки, гдеs.seat_noне NULL. Поэтому для «сколько реально мест у модели» берутCOUNT(s.seat_no)— у самолёта без мест получится 0.
Практика
8- Тест 1 — Что станет с самолётами без мест в «airplanes LEFT JOIN seats … WHERE s.fare_conditions = 'Business'»?
- Тест 2 — В «airplanes LEFT JOIN seats» у самолёта нет ни одного места. Что дадут COUNT(s.seat_no) и COUNT(*)?
- Задача 1 — Самолёты без мест (LEFT JOIN)
- Задача 2 — Число мест по моделям (LEFT JOIN + COUNT)
- Задача 3 — Выручка по статусам рейсов
- Задача 4 — Бизнес-мест по моделям
- Задача 5 — Пассажиров на рейс
- Задача 6 — Страны с 50+ маршрутами вылета (HAVING)
Задачи решаются прямо здесь, в браузере, на учебной базе — нужна только бесплатная регистрация, чтобы сохранялись ответы и прогресс.
Потренируйтесь в тренажёре
13Задачи на ту же тему, но на другой базе — продажи магазина электроники. Хороший способ проверить, что тема понятна, а не просто запомнилась на примерах урока.
- средняяВыручка по брендам
- средняяВыручка по сегментам
- средняяВыручка по способу оплаты
- средняяВыручка по сезонам
- средняяВыручка по типу устройства