O ile mi wiadomo, kolejność przetwarzania kwerend logicznych, która jest konceptualną kolejnością interpretacji, zaczyna się od FROM w następujący sposób:
- OD
- GDZIE
- GRUPUJ WEDŁUG
- MAJĄCY
- WYBIERZ
- ZAMÓW PRZEZ
Po tej liście łatwo jest zrozumieć, dlaczego nie można wybrać WYBIERAJ aliasów w klauzuli WHERE, ponieważ alias nie został jeszcze utworzony. T-SQL (SQL Server) ściśle przestrzega tego i nie możesz używać aliasów SELECT, dopóki nie przejdziesz SELECT.
Ale w MySQL możliwe jest użycie aliasów SELECT w klauzuli HAVING, mimo że powinno (logicznie) być przetwarzane przed klauzulą SELECT. Jak to mozliwe?
Dać przykład:
SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING Amount>1;
Instrukcja jest niepoprawna w języku T-SQL (ponieważ HAVING odnosi się do aliasu SELECT Amount
) ...
Msg 207, Level 16, State 1, Line 5
Invalid column name 'Amount'.
... ale działa dobrze w MySQL.
W oparciu o to zastanawiam się:
- Czy MySQL używa skrótu w regułach SQL, aby pomóc użytkownikowi? Może przy użyciu pewnego rodzaju analizy wstępnej?
- Czy też MySQL używa innej pojęciowej kolejności interpretacji niż ta, którą przestrzegałem wszystkich RDBMS?
SELECT C, ROW_NUMBER() OVER (ORDER BY X) AS RN FROM T GROUP BY C HAVING RN = 1
będzie problematyczne, jak ROW_NUMBER
biegnie poHAVING
SELECT @rownum:=@rownum + 1 as row ...
. Być może powodem, dla którego obsługują aliasy SELECT, jest po prostu fakt, że mogą, ponieważ nie obsługują rzeczy, które uniemożliwiłyby ... kto wie? :)
HAVING
i SELECT
klauzula mogą być zamienione. Tak więc nie ma w tym dwuznaczności i może uprościć wygląd kodu, gdy występują potworne wyrażenia SELECT
.