61. Найти пользователей, которые летали только экономом #
Условие задачи:
📌 Нужно выбрать уникальные user_id, которые летали только по билетам класса ECONOMY.
Если у пользователя хотя бы один билет BUSINESS, он не должен попасть в выборку.
Данные:
ticket_id | user_id | ticket_type | price
-----------+---------+--------------+-------
110 | 500 | 'ECONOMY' | 10000
220 | 600 | 'BUSINESS' | 35000
330 | 600 | 'ECONOMY' | 15000
440 | 750 | 'ECONOMY' | 12000
550 | 800 | 'BUSINESS' | 40000
660 | 750 | 'ECONOMY' | 5000
Спойлеры к решению
Подсказки
💡 Нужно сгруппировать билеты по
💡 Пользователь годится, если
💡 Или: сгруппировать и проверить
💡 Или: исключить тех, у кого есть BUSINESS.
user_id.💡 Пользователь годится, если
MIN(ticket_type) = MAX(ticket_type) = 'ECONOMY'.💡 Или: сгруппировать и проверить
COUNT(*) = COUNT(CASE WHEN ticket_type='ECONOMY' THEN 1 END).💡 Или: исключить тех, у кого есть BUSINESS.
Решение
✔️ Вариант 1 — через GROUP BY + HAVING #
SELECT user_id
FROM tickets
GROUP BY user_id
HAVING COUNT(*) = COUNT(CASE WHEN ticket_type = 'ECONOMY' THEN 1 END);
Логика:
Если общее число билетов = числу ECONOMY-билетов → других классов нет.
✔️ Вариант 2 — «запретить бизнес» (тоже верно) #
SELECT user_id
FROM tickets
GROUP BY user_id
HAVING SUM(CASE WHEN ticket_type = 'BUSINESS' THEN 1 ELSE 0 END) = 0;
✔️ Вариант 3 — через NOT EXISTS #
SELECT DISTINCT t1.user_id
FROM tickets t1
WHERE NOT EXISTS (
SELECT 1
FROM tickets t2
WHERE t2.user_id = t1.user_id
AND t2.ticket_type = 'BUSINESS'
);
✔️ Результат для данных из задания: #
| user_id |
|---|
| 500 |
| 750 |
500 — только ECONOMY
750 — только ECONOMY
600 — есть и ECONOMY, и BUSINESS → не подходит
800 — только BUSINESS → тоже не подходит