Порядок выполнения запроса на сервере отличается от порядка в котором мы пишем запросы.
И чтобы было понятнее почему, например, мы в HAVING
или WHERE
мы не можем использовать имена выражений из SELECT
, нужно посмотреть на порядок выполнения команд на сервере:
Сначала определяется таблица, из которой выбираются данные с помощью FROM
, затем отбираются записи в соответствии с условием WHERE
. Выбранные данные группируются с помощью GROUP BY
, и из сгруппированных записей выбираются только те, которые удовлетворяют условию после HAVING
. Потом уже выполняется SELECT
— вычисляются выражения, присваиваются имена. И в самом конце происходит сортировка ORDER BY
.
Этот порядок не соответствует синтаксическому порядку общего представления оператора SELECT, который ближе к естественному языку:
Пример:
SELECT author, SUM(price * amount) as Cost
FROM book
WHERE title <> 'Идиот' AND title <> 'Белая гвардия'
GROUP BY author
HAVING SUM(price * amount) > 5000
ORDER BY Cost DESC
Это пример из Степика, где у нас есть база данных, в которой автор, название книги, стоимость и количество книг.
В примере выше мы выбираем автора, считаем общую стоимость экземпляров книг у автора, затем указываем из какой таблицы берем данные. Указываем условие, группируем, фильтруем по стоимости экземпляров и затем сортируем.
Можно заметить, что в выражении HAVING
мы использовали SUM(price * amount)
, а не название Cost
, которое было задано в SELECT
.
Всё это потому что фактически при запросе этого названия еще не будет существовать на момент выполнения HAVING
. Как и было написано ранее.