为什么我不能在下一个SELECT表达式中使用列别名?

时间:2016-01-22 21:03:20

标签: sql postgresql column-alias

我可以修改下一个以在表达式avg_time中使用列别名cntROUND(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;

它引发了下一个错误:

ERROR:  column "avg_time" does not exist
LINE 7:  ROUND(avg_time * cnt, 2) as slowdown, path

然而,下一步工作正常(使用主要表达式而不是列别名:

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;

4 个答案:

答案 0 :(得分:4)

您可以在GROUP BYHAVING中使用之前创建的别名,但不能在SELECTWHERE中使用,因为该指令会处理{{1}的所有部分在同一时间,查询还不知道该值。

解决方案将查询封装在子查询中,然后别名在外面可用。

SELECT

答案 1 :(得分:1)

查询的执行顺序与其编写方式不同。 "将军" position是以这个顺序评估子句:

FROM
WHERE
GROUP BY
HAVING
SELECT
ORDER BY

因此列别名对于大多数查询都是未知的,直到select子句完成(这就是可以使用别名的原因在ORDER BY子句中)。但是,from子句中建立的表别名在子句的排序位置被理解。

最常见的解决方法是将查询封装到"派生表"

建议阅读:Order Of Execution of the SQL query

注意:不同的SQL dbms在使用alises方面有不同的具体规则

答案 2 :(得分:1)

重复表达式:

SELECT *, 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) x
ORDER BY avg_time DESC
LIMIT 10;

或使用子查询:

float floatArr[] = {1.2, 1.8, 2.1, 2.5, 3.2};
unsigned short usArr[5];
// I could do this
std::copy(floatArr, 5, usArr);

答案 3 :(得分:1)

在实际创建虚拟关系之前,别名不可用,如果要使用别名本身执行其他表达式,则必须使用子查询创建虚拟关系,而不是在其上运行其他查询。所以我会将您的查询修改为以下内容:

SELECT stddev_time, max_time, avg_time, min_time, ROUND(avg_time * cnt, 2) as slowdown, path 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, 
    ROUND(AVG(time) * COUNT(path), 2) as slowdown, path
FROM 
    loadtime
GROUP BY
    path
ORDER BY
    avg_time DESC
LIMIT 10;
)

我想在此处添加第二个查询有效的原因,因为查询计划程序会直接在您要查询的表中识别这些列。