Насколько мне известно, в SQL логический порядок обработки запросов, который является концептуальным порядком интерпретации, начинается с FROM следующим образом:
- ИЗ
- ГДЕ
- ГРУППА ПО
- HAVING
- ВЫБРАТЬ
- СОРТИРОВАТЬ ПО
Из этого списка легко понять, почему в предложении WHERE нельзя использовать псевдонимы SELECT, поскольку псевдоним еще не создан. T-SQL (SQL Server) строго следует этому, и вы не можете использовать псевдонимы SELECT, пока не пройдете SELECT.
Но в MySQL можно использовать псевдонимы SELECT в предложении HAVING, даже если он должен (логически) обрабатываться до предложения SELECT. Как это может быть возможным?
Чтобы привести пример:
SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING Amount>1;
Оператор недопустим в T-SQL (потому что HAVING ссылается на псевдоним SELECT Amount
) ...
Msg 207, Level 16, State 1, Line 5
Invalid column name 'Amount'.
... но отлично работает в MySQL.
Исходя из этого, мне интересно:
- MySQL использует ярлык в правилах SQL, чтобы помочь пользователю? Может быть, с помощью какого-то предварительного анализа?
- Или MySQL использует иной концептуальный порядок интерпретации, чем тот, который я следовал всем СУБД?
mysql
database-internals
Олина
источник
источник
SELECT C, ROW_NUMBER() OVER (ORDER BY X) AS RN FROM T GROUP BY C HAVING RN = 1
будет проблематично , какROW_NUMBER
бежит послеHAVING
SELECT @rownum:=@rownum + 1 as row ...
. Возможно, причина, по которой они поддерживают псевдонимы SELECT, заключается просто в том, что они могут, из-за того, что они не поддерживают вещи, которые делают невозможным ... кто знает? :)HAVING
иSELECT
предложения можно поменять местами. Таким образом, в этом нет никакой двусмысленности, и он может упростить внешний вид кода при наличии чудовищных выраженийSELECT
.distincts
) ...Alias in the Having
несмотря на тот жеExplain
результат. Так что некоторые изменения с оптимизатором происходят.Ответы:
Хорошо, когда у вас есть вопрос такого рода, лучшим источником информации IMHO является документация MySQL. Теперь к делу. Это поведение расширения MySql,
GROUP BY
которое включено по умолчанию.Если вы хотите стандартное поведение, вы можете отключить это расширение с помощью
sql_mode
ONLY_FULL_GROUP_BY
Если вы попытаетесь выполнить вышеупомянутый запрос в
ONLY_FULL_GROUP_BY
sql_mode, вы получите следующее сообщение об ошибке:Вот демо SQLFiddle
Поэтому вам решать, как настроить и использовать свой экземпляр MySQL.
источник
ORDER BY
Например, он может быть обработан гораздо раньше, чем теоретически, если оптимизатор обнаружит, что строки могут быть изначально считаны в порядке, соответствующем индексу, который уже находится в желаемом порядке.Хороший вопрос.
Я думаю, что вы должны запустить эти запросы
и проверьте, как запрос переписан. я уверен, что оптимизатор запросов заменит Amount на COUNT (*)
Как это происходит с
после оптимизатора запросов это примерно так.
источник