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?
mysql
database-internals
Ohlin
fuente
fuente
SELECT C, ROW_NUMBER() OVER (ORDER BY X) AS RN FROM T GROUP BY C HAVING RN = 1
será problemático ya que lasROW_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 laSELECT
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 monstruosasSELECT
.distincts
) ... aAlias in the Having
pesar de la mismaExplain
salida. Entonces, está ocurriendo alguna variación con el Optimizador.Respuestas:
Bueno, cuando tiene una pregunta de este tipo, la mejor fuente de información en mi humilde opinión es la documentación de MySQL. Ahora al grano. Este es el comportamiento de la extensión MySql
GROUP BY
que está habilitada de forma predeterminada.Si desea un comportamiento estándar, puede deshabilitar esta extensión con
sql_mode
ONLY_FULL_GROUP_BY
Si intenta ejecutar la consulta mencionada anteriormente en
ONLY_FULL_GROUP_BY
sql_mode, recibirá el siguiente mensaje de error:Aquí está la demostración SQLFiddle
Por lo tanto, depende de usted cómo configurar y usar su instancia de MySQL.
fuente
ORDER BY
, por ejemplo, podría manejarse mucho antes de lo que teóricamente es, si el optimizador encuentra que las filas pueden leerse inicialmente en orden desde un índice que ya está en el orden deseado.Buena pregunta.
Creo que deberías ejecutar estas consultas
y verifique cómo se reescribe la consulta. Estoy bastante seguro de que el optimizador de consultas reemplaza Amount con COUNT (*)
Como lo hace con
después del optimizador de consultas es algo como esto.
fuente