🔥 Live Coding: anti-join / NOT EXISTS 📌 Задача
Есть таблицы:
employees
employee_id department_id
employee_events
employee_id event_type — training / promotion / etc event_time
Нужно найти сотрудников, которые: 👉 ни разу не проходили обучение (event_type = 'training')
⚠️ Важно
• если у сотрудника хотя бы одно событие training → он не подходит • если у сотрудника вообще нет событий → он подходит • могут быть дубликаты событий
📊 На выходе хотим получить
• employee_id
🧪 Решение select e.employee_id from employees e where not exists ( select 1 from employee_events ev where ev.employee_id = e.employee_id and ev.event_type = 'training' ) 🧠 Как здесь думаем Берём каждого сотрудника из employees Проверяем: 👉 есть ли у него хотя бы одно событие training Если есть → exists = true → исключаем Если нет → exists = false → оставляем
👉 NOT EXISTS = “не найдено ни одной строки”
⚠️ Где можно ошибиться
❌ Написать так:
where ev.event_type != 'training'
👉 это не anti-join
Почему: если у сотрудника есть:
training promotion
он всё равно попадёт в результат ❌
❌ Сделать INNER JOIN
👉 потеряются сотрудники без событий а они нам как раз нужны
💡 Альтернативный вариант select e.employee_id from employees e left join employee_events ev on e.employee_id = ev.employee_id and ev.event_type = 'training' where ev.employee_id is null
👉 логика та же: если join не нашёл training → значит его нет
🎯 Вывод
Anti-join = поиск тех, у кого НЕ было события
Лучший паттерн: 👉 NOT EXISTS
Почему:
корректно работает с дубликатами не ломается на сложной логике читается как бизнес-условие