Напишите SQL запрос для выбора профилей с количеством постов больше десяти
Что проверяют
Разницу между WHERE и HAVING и готовность считать агрегаты в базе, а не в приложении. На java-собеседовании вопрос почти всегда продолжается вторым: как то же самое сделать через JPA и не получить N+1.
Как отвечать
select p.id, p.name, count(po.id) as post_count
from profiles p
join posts po on po.profile_id = p.id
group by p.id, p.name
having count(po.id) > 10
order by post_count desc;Объясните порядок вычисления: WHERE отсеивает строки до группировки, HAVING работает уже по готовым группам, поэтому условие на count может стоять только в нём. Если нужно ограничить и сами посты, например считать только опубликованные, это условие идёт в WHERE и обходится дешевле, потому что уменьшает объём до агрегации.
Про колонки в GROUP BY скажите честно: в строгом режиме перечисляются все неагрегированные поля, а Postgres разрешает опустить те, что функционально зависят от первичного ключа. Псевдоним post_count в HAVING по стандарту недоступен, MySQL его принимает. Для Java добавьте, что такой запрос живёт в репозитории нативным или как JPQL с проекцией в интерфейс, а тянуть коллекцию постов в сущность и звать size() нельзя: это выборка всех строк ради одного числа.
Где спотыкаются
Пишут условие на количество в WHERE. База отвечает, что агрегат здесь запрещён, и кандидат начинает сочинять подзапрос вместо того, чтобы вспомнить про HAVING.
Второе: считают в приложении. Достают профили, для каждого запрашивают посты и фильтруют стримом. Это и есть N+1: сотни запросов и вся таблица в памяти там, где базе хватает одного прохода.
Третье: берут count(*) после внешнего соединения. Для профиля без постов такой счётчик вернёт единицу, а не ноль. В этой задаче порог ошибку прячет, но привычка опасная, и на соседнем вопросе про не больше пяти она сразу даёт неверный ответ.