Чем отличается WHERE от HAVING?
Обсудим такой популярный вопрос на собеседовании, как «Чем отличается WHERE от HAVING»?
SELECT username, COUNT(*) FROM table WHERE username = ‘Anna’ GROUP BY username HAVING COUNT(*)>1
Ой, скажет кто-то, зачем же спрашивать такие банальности? Как ни странно, довольно много разработчиков даже с сертификатами по SQL quering не понимают, что происходит в HAVING.
Давайте разберёмся. В сущности, HAVING очень похож на WHERE - это тоже фильтр. Вы можете написать в HAVING name = ‘Anna’, как и в WHERE, и ошибки не будет.
В чём же ключевое различие?
Во-первых, в HAVING и только в нём можно писать условия по агрегатным функциям (SUM, COUNT, MAX, MIN и т. д.). То есть если вы хотите сделать что-то вроде COUNT() > 10, то это возможно сделать только в HAVING*.
"Почему бы не оставить только HAVING?" - спросите вы. Всё кроется в том, как SQL Server выполняет запрос, в каком порядке происходит его разбор и работа с данными. WHERE выполняется до формирования групп GROUP BY. Это нужно для того, чтобы можно было оперировать как можно меньшим количеством данных и сэкономить ресурсы сервера и время пользователя.
Следующим этапом формируются группы, которые указаны в GROUP BY. После того как сформированы группы, можно накладывать условия на результаты агрегатных функций. И тут как раз наступает очередь HAVING: выполняются условия, которые вы задали.
Главное отличие HAVING от WHERE в том, что в HAVING можно наложить условия на результаты группировки, потому что порядок исполнения запроса устроен таким образом, что на этапе, когда выполняется WHERE, ещё нет групп, а HAVING выполняется уже после формирования групп.
Остались вопросы? Пишите их в комментариях!