En SQL, que yo sepa, el orden de procesamiento de consultas lógicas, que es el orden de interpretación conceptual, comienza con FROM de la siguiente manera:
- DESDE
- DÓNDE
- AGRUPAR POR
- TENIENDO
- SELECCIONE
- ORDENAR POR
Siguiendo esta lista, es fácil ver por qué no puede tener alias SELECT en una cláusula WHERE, porque el alias aún no se ha creado. T-SQL (SQL Server) sigue esto estrictamente y no puede usar alias SELECT hasta que haya pasado SELECT.
Pero en MySQL es posible usar alias SELECT en la cláusula HAVING aunque debería (lógicamente) procesarse antes de la cláusula SELECT. como puede ser esto posible?
Para dar un ejemplo:
SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING Amount>1;
La declaración no es válida en T-SQL (porque HAVING se refiere al alias SELECT Amount
) ...
Msg 207, Level 16, State 1, Line 5
Invalid column name 'Amount'.
... pero funciona bien en MySQL.
Basado en esto, me pregunto:
- ¿MySQL está tomando un atajo en las reglas de SQL para ayudar al usuario? ¿Quizás usando algún tipo de preanálisis?
- ¿O MySQL está usando un orden de interpretación conceptual diferente al que yo creía que seguían todos los RDBMS?
SELECT C, ROW_NUMBER() OVER (ORDER BY X) AS RN FROM T GROUP BY C HAVING RN = 1
será problemático ya que las ROW_NUMBER
carreras después delHAVING
SELECT @rownum:=@rownum + 1 as row ...
. Tal vez la razón por la que admiten alias SELECT simplemente es porque pueden hacerlo, debido al hecho de que no admiten cosas que lo harían imposible ... ¿quién sabe? :)
HAVING
y la SELECT
cláusula pueden intercambiarse. Por lo tanto, no hay ambigüedad al hacer esto y puede simplificar la apariencia del código cuando hay expresiones monstruosas SELECT
.