En SQL, pour autant que je sache, l'ordre de traitement des requêtes logiques, qui est l'ordre d'interprétation conceptuelle, commence par FROM de la manière suivante:
- DE
- OÙ
- PAR GROUPE
- AYANT
- SÉLECTIONNER
- COMMANDÉ PAR
Après cette liste, il est facile de comprendre pourquoi vous ne pouvez pas avoir d'alias SELECT dans une clause WHERE, car l'alias n'a pas encore été créé. T-SQL (SQL Server) suit strictement cela et vous ne pouvez pas utiliser les alias SELECT jusqu'à ce que vous ayez passé SELECT.
Mais dans MySQL, il est possible d'utiliser des alias SELECT dans la clause HAVING même s'il doit (logiquement) être traité avant la clause SELECT. Comment cela est-il possible?
Pour donner un exemple:
SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING Amount>1;
L'instruction n'est pas valide dans T-SQL (car HAVING fait référence à l'alias SELECT Amount
) ...
Msg 207, Level 16, State 1, Line 5
Invalid column name 'Amount'.
... mais fonctionne très bien dans MySQL.
Sur cette base, je me demande:
- MySQL prend-il un raccourci dans les règles SQL pour aider l'utilisateur? Peut-être en utilisant une sorte de pré-analyse?
- Ou est-ce que MySQL utilise un ordre d'interprétation conceptuelle différent de celui que je pensais que tous les SGBDR suivaient?
SELECT C, ROW_NUMBER() OVER (ORDER BY X) AS RN FROM T GROUP BY C HAVING RN = 1
sera problématique car les ROW_NUMBER
runs après leHAVING
SELECT @rownum:=@rownum + 1 as row ...
. Peut-être que la raison pour laquelle ils prennent en charge les alias SELECT est simplement parce qu'ils le peuvent, car ils ne prennent pas en charge les éléments qui rendraient cela impossible ... qui sait? :)
HAVING
et la SELECT
clause peuvent être échangés. Ainsi, il n'y a aucune ambiguïté en faisant cela et peut simplifier l'apparence du code lorsqu'il y a des expressions monstrueuses dans SELECT
.