可以使以下声明起作用吗?:
SELECT
id AS "ID",
unnest(agent_ids) AS "AgentID",
idtotitle('users', "AgentID") AS "AgentName", -- lookup agent name
from users;
错误:列“AgentID”不存在第4行:idtotitle('users', “AgentID”)AS“AgentName”
似乎告诉我无法在同一语句中引用unnested列值。我可以将整个事物包装在一个子选择中,但由于该语句是由不支持子选择语法的现有代码生成的,所以我希望尽可能避免这种情况。
我也很好奇为什么上面的内容不起作用。
编辑:不是特定于unexst(),这也失败了:
SELECT
id AS "UserID",
'User ' || "UserID" AS "UserName"
FROM users;
错误:列“UserID”不存在
所以你不能在同一个语句中访问你创建/重命名的列?
答案 0 :(得分:3)
您已经知道解决方案 - 使用子查询,CTE或重复表达式。
原因很简单。 SQL标准未指定select
子句中表达式的评估顺序。您可能认为从左到右按照书面处理它们是合乎逻辑的,但定义SQL的权力从未强制要求。
因此,可以在定义列别名的表达式之前评估使用列别名的表达式 - 从而导致问题。为了防止这种情况,SQL引擎不允许您在定义的同一级别使用列别名。
答案 1 :(得分:1)
有趣的是,您无法重用在同一SELECT
子句中SELECT
子句中声明的列别名。从技术上讲,没有理由缺少此功能。数据库可以检测引用依赖图并检查周期,并允许非循环引用,但这在大多数数据库中根本不可能(有些数据库允许某些“相同范围列引用”,特别是在窗口函数时参与其中)。
以下是PostgreSQL中可能的概述:
SELECT
范围内声明的列别名:select 1 as "ID", "ID" + 1; -- This would be very useful but isn't possible
select 1 as "ID" where "ID" = 1; -- This would be very useful but isn't possible
select 1 as "ID" having "ID" = 1; -- This doesn't even make sense
SELECT
范围内声明的列别名:select 1 as "ID" group by "ID"; -- Only few databases allow this
select 1 as "ID" order by "ID"; -- This is explicitly allowed by the SQL standard
因此,正如其他人所提到的,就您的问题而言,您将不得不求助于在表格中生成计算出的值,例如:公用表表达式或派生表。