ser*_*ach 6 sql postgresql column-alias
我可以修改使用的列别名下一avg_time并cnt在表达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;
Run Code Online (Sandbox Code Playgroud)
它将引发下一个错误:
ERROR: column "avg_time" does not exist
LINE 7: ROUND(avg_time * cnt, 2) as slowdown, path
Run Code Online (Sandbox Code Playgroud)
但是,下一个可以正常工作(使用主表达式而不是列别名:
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;
Run Code Online (Sandbox Code Playgroud)
查询的执行顺序(以及表达式和别名的求值)与其编写的方式不同。“一般”立场是按以下顺序评估子句:
FROM
WHERE
GROUP BY
HAVING
SELECT
ORDER BY
Run Code Online (Sandbox Code Playgroud)
因此,在 select 子句完成之前,大多数查询都不知道列别名(这就是您可以在 ORDER BY 子句中使用别名的原因)。然而,在 from 子句中建立的表别名可以在 where to order by 子句中理解。
最常见的解决方法是将查询封装到“派生表”中
建议阅读:SQL 查询的执行顺序
注意:不同的 SQL dbms 对于别名的使用有不同的具体规则
编辑
提醒读者逻辑子句序列背后的目的是,通常(但并非总是)别名仅在声明别名的子句之后才变得可引用。最常见的是子句中声明的别名SELECT可以被子句使用ORDER BY。特别是,子句中声明的别名SELECT不能在同一SELECT子句中引用。
但请注意,由于产品的差异,并非每个 dbms 都会以这种方式运行
您可以在GROUP BYor HAVING语句中使用先前创建的别名,但不能在SELECTor WHERE语句中使用。这是因为程序同时处理所有SELECT语句,并且尚不知道别名的值。
解决方案是将查询封装在子查询中,然后在外部使用别名。
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;
Run Code Online (Sandbox Code Playgroud)