¿Por qué no puedo utilizar alias de columna en la siguiente expresión SELECT?
¿Puedo modificar el siguiente para usar los alias de columna avg_time
y cnt
en una expresión ROUND(avg_time * cnt, 2)
?
SELECT
COALESCE(ROUND(stddev_samp(time), 2), 0) as stddev_time,
MAX(time) as max_time,
ROUND(AVG(time), 2) as avg_time,
MIN(time) as min_time,
COUNT(path) as cnt,
ROUND(avg_time * cnt, 2) as slowdown, path
FROM
loadtime
GROUP BY
path
ORDER BY
avg_time DESC
LIMIT 10;
Genera el siguiente error:
ERROR: column "avg_time" does not exist
LINE 7: ROUND(avg_time * cnt, 2) as slowdown, path
El siguiente, sin embargo, funciona bien (use expresiones primarias en lugar de alias de columna:
SELECT
COALESCE(ROUND(stddev_samp(time), 2), 0) as stddev_time,
MAX(time) as max_time,
ROUND(AVG(time), 2) as avg_time,
MIN(time) as min_time,
COUNT(path) as cnt,
ROUND(AVG(time) * COUNT(path), 2) as slowdown, path
FROM
loadtime
GROUP BY
path
ORDER BY
avg_time DESC
LIMIT 10;
Puede utilizar un alias creado previamente en la declaración GROUP BY
o HAVING
pero no en una declaración SELECT
o WHERE
. Esto se debe a que el programa procesa todos losSELECT
declaraciones al mismo tiempo y aún no conoce el valor del alias.
La solución es encapsular la consulta en una subconsulta y luego el alias estará disponible afuera.
SELECT stddev_time, max_time, avg_time, min_time, cnt,
ROUND(avg_time * cnt, 2) as slowdown
FROM (
SELECT
COALESCE(ROUND(stddev_samp(time), 2), 0) as stddev_time,
MAX(time) as max_time,
ROUND(AVG(time), 2) as avg_time,
MIN(time) as min_time,
COUNT(path) as cnt,
path
FROM
loadtime
GROUP BY
path
ORDER BY
avg_time DESC
LIMIT 10
) X;
El orden de ejecución de una consulta (y por tanto la evaluación de expresiones y alias) NO es el mismo que la forma en que está escrita. La posición "general" es que las cláusulas se evalúan en esta secuencia:
FROM
WHERE
GROUP BY
HAVING
SELECT
ORDER BY
Por lo tanto, los alias de las columnas son desconocidos para la mayor parte de la consulta hasta que se completa la cláusula de selección (y es por eso que puede usar alias en la cláusula ORDER BY). Sin embargo los alias de tablas que se establecen en la cláusula from se entienden en las cláusulas donde ordenar por.
La solución más común es encapsular su consulta en una "tabla derivada".
Lectura sugerida: Orden de ejecución de la consulta SQL
Nota: diferentes bases de datos SQL tienen diferentes reglas específicas con respecto al uso de alias
EDITAR
El propósito de recordar a los lectores la secuencia lógica de la cláusula es que a menudo ( pero no siempre ) los alias solo se vuelven referenciables DESPUÉS de la cláusula donde se declara el alias. El más común es que SELECT
la cláusula pueda utilizar los alias declarados en la ORDER BY
cláusula. En particular, SELECT
no se puede hacer referencia a un alias declarado en una cláusula dentro de la misma SELECT
cláusula.
Pero tenga en cuenta que, debido a diferencias en los productos, no todos los dbms se comportarán de esta manera.