In SQL beginnt die logische Abfrageabarbeitungsreihenfolge, die die konzeptionelle Interpretationsreihenfolge darstellt, meines Wissens mit FROM auf folgende Weise:
- VON
- WO
- GRUPPIERE NACH
- HABEN
- WÄHLEN
- SORTIEREN NACH
Anhand dieser Liste können Sie leicht erkennen, warum in einer WHERE-Klausel keine SELECT-Aliase enthalten sind, da der Alias noch nicht erstellt wurde. T-SQL (SQL Server) befolgt dies genau und Sie können SELECT-Aliase erst verwenden, wenn Sie SELECT bestanden haben.
In MySQL ist es jedoch möglich, SELECT-Aliase in der HAVING-Klausel zu verwenden, obwohl sie (logischerweise) vor der SELECT-Klausel verarbeitet werden sollten. Wie kann das möglich sein?
Um ein Beispiel zu geben:
SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING Amount>1;
Die Anweisung ist in T-SQL ungültig (da HAVING auf den SELECT-Alias verweist Amount
) ...
Msg 207, Level 16, State 1, Line 5
Invalid column name 'Amount'.
... funktioniert aber gut in MySQL.
Aufgrund dessen frage ich mich:
- Übernimmt MySQL eine Verknüpfung in den SQL-Regeln, um dem Benutzer zu helfen? Vielleicht mit einer Art Voranalyse?
- Oder verwendet MySQL eine andere konzeptionelle Interpretationsreihenfolge als die, der ich, obwohl alle RDBMS folgten?
SELECT C, ROW_NUMBER() OVER (ORDER BY X) AS RN FROM T GROUP BY C HAVING RN = 1
wird es problematisch wie die ROW_NUMBER
Läufe nach demHAVING
SELECT @rownum:=@rownum + 1 as row ...
. Vielleicht liegt der Grund, warum sie SELECT-Aliase unterstützen, einfach darin, dass sie dies können, weil sie keine Dinge unterstützen, die es unmöglich machen würden ... wer weiß? :)
HAVING
und der SELECT
Klausel vertauscht werden , solange es keine Fenster- / Ranglistenfunktionen gibt . Dies ist also nicht mehr eindeutig und kann das Erscheinungsbild des Codes vereinfachen, wenn monströse Ausdrücke enthalten sind SELECT
.
distincts
) ... mit Alias in the Having
der gleichen Explain
Ausgabe erzielt . Es gibt also einige Variationen mit dem Optimierer.