Когда вы сталкиваетесь с SQL-задачей на собеседовании или в обучении, важно действовать системно. Разберём по шагам, как подходить к решению любой задачи.
💡Шаг 1. Внимательно читаем условие
Прежде чем писать код, нужно точно понять, что от вас требуется.
Пример задачи:
"Вывести имена всех пассажиров, которые летали в бизнес-классе (class = 'Business'), но ни разу не летали в экономе (class = 'Economy')."
🔍 Что нужно выяснить:
1. Какие таблицы есть в базе? (например, `Passenger`, `Ticket`, `Flight`)
2. Какие поля в этих таблицах? (`id`, `name`, `class`, `flight_id` и т. д.)
3. Какие условия фильтрации? (`class = 'Business'` и отсутствие `class = 'Economy'`)
❌ Ошибки новичков:
- Не дочитали условие и упустили часть задачи (например, забыли про условие "ни разу не летали в экономе").
- Не знают структуру базы данных (надо уточнить у интервьюера или посмотреть схему).
💡Шаг 2. Определяем, какие таблицы и JOIN-ы нужны
Чаще всего данные хранятся в нескольких таблицах, и их нужно соединять.
Пример:
- `Passenger` — информация о пассажирах (`id`, `name`).
- `Ticket` — информация о билетах (`passenger_id`, `flight_id`, `class`).
🔍 Как соединять?
- Пассажир (`Passenger`) может иметь несколько билетов (`Ticket`), значит, связь один ко многим.
- Нужен `JOIN` по `passenger_id`.
Запрос с JOIN:
❌ Ошибки новичков:
- Используют `JOIN`, но не проверяют, все ли данные попадут в выборку (может, нужен `LEFT JOIN`?).
- Путают порядок таблиц в `JOIN`.
💡Шаг 3. Фильтруем данные (WHERE)
Теперь добавляем условия из задачи.
🔍 Условия:
1. Летал в бизнес-классе (`class = 'Business'`).
2. Ни разу не летал в экономе (`class = 'Economy'`).
Первый вариант (неправильный):
Проблема: Один и тот же билет не может быть одновременно `Business` и `Economy`, но у пассажира может быть несколько билетов!
Правильный вариант:
❌ Ошибки новичков:
- Пытаются проверить оба условия в одном `WHERE` без подзапроса.
- Забывают про `NOT IN` / `NOT EXISTS` для исключения записей.
💡 Шаг 4. Проверяем на дубликаты (DISTINCT, GROUP BY)
Если пассажир летал несколько раз в бизнес-классе, его имя выведется несколько раз. Используем `DISTINCT` или `GROUP BY`.
🔍 Итоговый запрос:
Альтернатива с GROUP BY:
❌ Ошибки новичков:
- Забывают про `DISTINCT`, получая дубликаты.
- Путают `WHERE` и `HAVING`.
💡 Шаг 5. Оптимизация и альтернативные решения
Иногда задачу можно решить разными способами. Например:
Через `EXISTS` и `NOT EXISTS`:
Плюсы:
- Читаемо и логично.
- Не требует `DISTINCT`, так как `EXISTS` проверяет наличие, а не создаёт дубли.
Минусы:
- Может быть менее эффективным на больших данных.
💡 Вывод: алгоритм решения SQL-задач
1. Разобрать условие (какие таблицы, поля, условия).
2. Определить JOIN-ы (какие таблицы связаны и как).
3. Добавить фильтрацию (`WHERE`, `HAVING`).
4. Убрать дубликаты (`DISTINCT`, `GROUP BY`).
5. Проверить альтернативные решения (`IN`, `EXISTS`, подзапросы).
Совет: Всегда тестируйте запрос на примере данных, чтобы убедиться, что он работает правильно! 🚀