抱歉,如果这是重复的,但是我还没有找到。为什么我不能用在我的定义列别名SELECT从ORDER BY当我使用 CASE?
SELECT
ORDER BY
CASE
考虑以下简单查询:
SELECT NewValue=CASE WHEN Value IS NULL THEN '<Null-Value>' ELSE Value END FROM dbo.TableA ORDER BY CASE WHEN NewValue='<Null-Value>' THEN 1 ELSE 0 END
结果是一个错误:
无效的列名“ NewValue”
这是一个sql小提琴。(替换ORDER BY NewValue用CASE WHEN...的是麓的注释掉)
ORDER BY NewValue
CASE WHEN...
我知道我可以使用ORDER BY CASE WHEN Value IS NULL THEN 1 ELSE 0 END像 这里 在这种情况下,但实际上在查询比较复杂,我想保持它尽可能地易读。我是否必须改用子查询或CTE,如果是这样,为什么呢?
ORDER BY CASE WHEN Value IS NULL THEN 1 ELSE 0 END
*由于Mikael Eriksson注释了 任何 与别名结合使用的表达式,因此进行了 *更新 。因此,即使是这个(无意义的查询)也由于相同的原因而失败:
SELECT '' As Empty FROM dbo.TableA ORDER BY Empty + ''
结果:
无效的列名“ Empty”。
因此在ORDER BY和表达式中都允许使用别名,但 不能同时使用两者 。为什么,实施起来太困难了?由于我主要是程序员,因此我将别名视为可以在表达式中简单使用的变量。
这与SQL dbms如何解析歧义名称有关。
我尚未在SQL标准中跟踪此行为,但在各个平台上似乎是一致的。这是正在发生的事情。
create table test ( col_1 integer, col_2 integer ); insert into test (col_1, col_2) values (1, 3), (2, 2), (3, 1);
别名“ col_1”为“ col_2”,并在ORDER BY子句中使用别名。dbms将ORDER BY中的“ col_2”解析为“ col_1”的别名,并按“ test”。“ col_1”中的值进行排序。
select col_1 as col_2 from test order by col_2; col_2 -- 1个 2个 3
同样,别名“ col_1”为“ col_2”,但在ORDER BY子句中使用表达式。dbms 不会 将“ col_2”解析为“ col_1”的别名,而是解析为“ test”。“ col_2”列。它按“ test”。“ col_2”中的值排序。
select col_1 as col_2 from test order by (col_2 || ''); col_2 -- 3 2个 1个
因此,在您的情况下,您的查询失败,因为dbms希望将表达式中的“ NewValue”解析为基表中的列名。但事实并非如此;这是列别名。
PostgreSQL的
PostgreSQL的Sorting Rows部分中记录了此行为。他们陈述的理由是减少歧义。
请注意,输出列名称必须独立存在,即不能在表达式中使用-例如,这是 不 正确的:
SELECT a + b AS sum, c FROM table1 ORDER BY sum + c; -- wrong
进行此限制是为了减少歧义。如果ORDER BY项是一个简单名称,可以匹配输出列名称或表表达式中的列,则仍然存在歧义。在这种情况下使用输出列。仅当您使用AS重命名输出列以使其与其他表列的名称匹配时,这才会引起混淆。
SQL Server 2008中的文档错误
一个 稍微 不同的问题,相对于在ORDER BY子句中的别名。
如果在SELECT列表中为列名加上别名,则只能在ORDER BY子句中使用别名。
除非我没有足够的咖啡因,否则那不是真的。在SQL Server 2008和SQL Server 2012中,此语句均按“测试”。“ col_1”排序。
select col_1 as col_2 from test order by col_1;