PostgreSQL:在同一查询中使用计算列

时间:2012-01-12 18:23:04

标签: sql postgresql calculated-columns

我在postgres中使用计算列时遇到问题。下面给出了一个在SQL中工作的类似代码,是否可以在PostgreSQL

中重新创建它
select cost_1, quantity_1, cost_2, quantity_2, 
      (cost_1 * quantity_1) as total_1,
      (cost_2 * quantity_2) as total_2,
      (calculated total_1 + calculated total_2) as total_3
from data;

PostgreSQL中,类似的代码返回错误:

  

列total_1和total_2不存在。

4 个答案:

答案 0 :(得分:43)

您需要将SELECT语句包装到派生表中,以便能够访问列别名:

select cost1,
       quantity_1,
       cost_2,
       quantity_2
       total_1 + total_2 as total_3
from (
    select cost_1, 
           quantity_1, 
           cost_2, 
           quantity_2, 
           (cost_1 * quantity_1) as total_1,
           (cost_2 * quantity_2) as total_2
    from data
) t

对此不会有任何性能损失。

(我真的对您的原始SQL语句在DBMS中运行感到惊讶)

答案 1 :(得分:11)

作为一项规则,您需要了解有关SELECT子句的两件事:

  • 虽然它是先写 ,但它被评估为 last ,但ORDER BY子句除外。这就是为什么你不能在WHERE子句中除之外的任何其他子句(特别是ORDER BY子句)中使用任何计算字段或别名。
  • SELECT子句中的计算在 parallel 中执行,或者至少按照它们的方式进行处理。这就是为什么你不能将一个计算用作另一个计算的原因。

所以,简短的回答是你做不到,这是设计的。

值得注意的例外是Microsoft Access,您可以在后续列和WHERE子句中使用计算。然而,虽然这很方便,但实际上并不是一个优点:不遵循上述原则效率较低。但对于轻型数据库来说这是可以的,这就是Access应该用于的。

如果您确实想要重复使用计算结果,则需要以子查询或公用表表达式的形式单独查询。 CTE更易于使用,因为它们更易于阅读。

修改

在不改变原始答案的要点的情况下,我想我可以补充一点,我认为这种解释可能有点意味深长。

现代DBMS在计划和优化查询方面投入了大量精力,因此,如果查询确实按特定顺序执行,则不再正确。据我所知,没有技术理由为什么优化器无法向前看并将计算结果合并到解析查询中,即使它只是替换表达式。

哦,好吧......

答案 2 :(得分:0)

select cost_1, quantity_1, cost_2, quantity_2, 
      cost_1 * quantity_1 as total_1,
      cost_2 * quantity_2 as total_2,
      (cost_1 * quantity_1 + cost_2 * quantity_2) as total_3
from data;

答案 3 :(得分:-4)

您正尝试在表达式中使用列别名。如果一个系统允许你这样做它只是语法糖。这应该适用于任何SQL方言。

select 
 cost_1
,quantity_1
,cost_2
,quantity_2
,cost_1 * quantity_1 as total_1
,cost_2 * quantity_2 as total_2
,(cost_1 * quantity_1) + (cost_2 * quantity_2) as total_3 

from data;