Что будет по результатам двух SQL-запросов, работающих с таблицами департаментов и работников?
Что проверяют
Умеете ли вы читать запрос и предсказывать результат, не запуская его. Для инженера данных это ежедневная работа: витрина собирается из соединений таблиц, и разница между двумя похожими запросами это разница между отчётом, где пустые департаменты есть, и отчётом, где они молча пропали.
Как отвечать
Разбирайте по шагам: какое соединение, что делает агрегат, по чему группировка. Классическая пара выглядит так:
select d.name, count(e.id) as cnt
from departments d
left join employees e on e.department_id = d.id
group by d.name;
select d.name, count(e.id) as cnt
from departments d
join employees e on e.department_id = d.id
group by d.name;Первый вернёт все департаменты, у пустых cnt будет ноль. Второй выкинет пустые департаменты из выдачи совсем. Дальше проговорите детали, ради которых вопрос и задают:
count(e.id)считает только не NULL значения, поэтому у пустого департамента ноль.count(*)в том же запросе дал бы единицу: строка от левой таблицы существует, просто поля правой в ней пустые.- условие по правой таблице в
whereпревращает внешнее соединение во внутреннее, потому что NULL не проходит сравнение. Фильтр правой таблицы ставят вon. - группировка по имени, а не по идентификатору, склеит два разных департамента с одинаковым названием в одну строку.
Где спотыкаются
Говорят, что у департамента без сотрудников в счётчике будет NULL. Нет: count по группе без строк возвращает ноль. NULL вернули бы sum, avg и max, и вот их уже приходится оборачивать в coalesce.
Второе: чинят потерянные строки условием where e.id is not null или наоборот дописывают фильтр по зарплате в where, не заметив, что он обнуляет весь смысл внешнего соединения.
Третье: забывают про размножение строк. Если на сотрудника в таблице несколько записей, счётчик посчитает строки соединения, а не людей, и тут нужен count(distinct e.id).