In SQL, per quanto ne so, l'ordine di elaborazione della query logica, che è l'ordine di interpretazione concettuale, inizia con FROM nel modo seguente:
- A PARTIRE DAL
- DOVE
- RAGGRUPPARE PER
- VISTA
- SELEZIONARE
- ORDINATO DA
Seguendo questo elenco è facile capire perché non è possibile avere alias SELECT in una clausola WHERE, poiché l'alias non è stato ancora creato. T-SQL (SQL Server) segue questo rigorosamente e non è possibile utilizzare gli alias SELECT fino a quando non si supera SELECT.
Ma in MySQL è possibile utilizzare gli alias SELECT nella clausola HAVING anche se dovrebbe (logicamente) essere elaborato prima della clausola SELECT. Come può essere possibile?
Per fare un esempio:
SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING Amount>1;
L'istruzione non è valida in T-SQL (poiché HAVING si riferisce all'alias SELECT Amount
) ...
Msg 207, Level 16, State 1, Line 5
Invalid column name 'Amount'.
... ma funziona benissimo in MySQL.
Sulla base di questo, mi chiedo:
- MySQL sta prendendo un collegamento nelle regole SQL per aiutare l'utente? Forse usando una sorta di pre-analisi?
- O MySQL sta usando un ordine di interpretazione concettuale diverso da quello che tutti i RDBMS stavano seguendo?
SELECT C, ROW_NUMBER() OVER (ORDER BY X) AS RN FROM T GROUP BY C HAVING RN = 1
sarà problematico in quanto le ROW_NUMBER
corse dopo ilHAVING
SELECT @rownum:=@rownum + 1 as row ...
. Forse il motivo per cui supportano semplicemente gli alias SELECT è perché possono, a causa del fatto che non supportano cose che renderebbero impossibile ... chi lo sa? :)
HAVING
e la SELECT
clausola possono essere scambiati. Quindi, non c'è ambiguità nel fare questo e può semplificare l'aspetto del codice quando ci sono espressioni mostruose in SELECT
.
distincts
) ... con Alias in the Having
lo stesso Explain
risultato. Quindi si stanno verificando alcune variazioni con l'ottimizzatore.