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?
mysql
database-internals
Ohlin
źródło
źródło
SELECT C, ROW_NUMBER() OVER (ORDER BY X) AS RN FROM T GROUP BY C HAVING RN = 1
będzie problematyczne, jakROW_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
iSELECT
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żeniaSELECT
.distincts
) ... zAlias in the Having
tym samymExplain
wynikiem. Tak więc dzieje się trochę zmian w Optymalizatorze.Odpowiedzi:
Cóż, jeśli masz takie pytanie, najlepszym źródłem informacji IMHO jest dokumentacja MySQL. Teraz do rzeczy. Jest to zachowanie rozszerzenia MySql,
GROUP BY
które jest domyślnie włączone.Jeśli chcesz mieć standardowe zachowanie, możesz wyłączyć to rozszerzenie za pomocą
sql_mode
ONLY_FULL_GROUP_BY
Jeśli spróbujesz wykonać wyżej wymienione zapytanie w
ONLY_FULL_GROUP_BY
trybie_sql, pojawi się następujący komunikat o błędzie:Oto wersja demonstracyjna SQLFiddle
Dlatego to od Ciebie zależy, jak skonfigurować i używać instancji MySQL.
źródło
ORDER BY
, na przykład może być obsługiwany znacznie wcześniej niż teoretycznie, jeśli optymalizator stwierdzi, że wiersze można początkowo odczytać w kolejności z indeksu, który jest już w pożądanej kolejności.Dobre pytanie.
Myślę, że powinieneś uruchomić te zapytania
i sprawdź, w jaki sposób zapytanie jest przepisywane. jestem całkiem pewien, że optymalizator zapytań zastąpił Kwotę COUNT (*)
Tak jak robi to z
po optymalizacji kwerendy jest coś takiego.
źródło