当前位置: 首页 > 面试题库 >

为什么我不能使用CASE引用ORDER BY中的列别名?

齐才艺
2023-03-14
问题内容

抱歉,如果这是重复的,但是我还没有找到。为什么我不能用在我的定义列别名SELECTORDER 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 NewValueCASE WHEN...的是麓的注释掉)

我知道我可以使用ORDER BY CASE WHEN Value IS NULL THEN 1 ELSE 0 END
这里

在这种情况下,但实际上在查询比较复杂,我想保持它尽可能地易读。我是否必须改用子查询或CTE,如果是这样,为什么呢?

*由于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;


 类似资料:
  • 问题内容: 当将多个列与以下数据框一起使用时,Pandas Apply函数存在一些问题 和以下功能 当我尝试使用以下功能时: 我收到错误消息: 我不明白此消息,我正确定义了名称。 非常感谢你在此问题上的任何帮助 更新资料 谢谢你的帮助。我确实在代码中犯了一些语法错误,索引应该放在’‘。但是,使用更复杂的功能仍然会遇到相同的问题,例如: 问题答案: 似乎你忘记了你的字符串。 在我看来,顺便说一句,以

  • 我了解在lambda中捕获此(修改对象属性)的正确方法如下: 但我对我所看到的以下特点感到好奇: 我感到困惑(并希望得到回答)的奇怪之处在于,为什么以下方法有效: 以及为什么我无法通过引用明确捕获此内容:

  • 我正在尝试使用文件系统。我的< code>CMakeLists.txt中有< code>-std=c 11 -std=c 1y。GCC版本为4.9.2。然而,我得到了一个错误: 使用的正确方法是什么?

  • 问题内容: 因此,我有一个名为Save.php的文件。 它需要两件事:一个文件和新内容。 您可以通过发送类似的请求来使用它。 ..但当然是对网址进行编码。:)为了简化和可读性,我不做任何编码。 该文件有效,但不是内容。 ..我发现.. .. 当稍后通过XHR获取JSON文件时尝试使用时,当然会抛出错误。 要保存内容,我只用.. 我该怎么做才能消除反斜线? 问题答案: 关闭在php.ini关闭。

  • 从TensorArray读取: 使用: 问题: 回溯(最近一次调用last):RLU培训中第130行的文件“\main.py”。train()文件“C:\Users\user\Documents\Projects\rl toolkit\rl_training.py”,第129行,在train self中_rpm,赛尔夫。批量大小,自行确定。梯度步数,记录步数b=self。在call result=

  • 问题内容: 对于什么可以/不能用作python dict的键,我有些困惑。 因此,元组是不可变的类型,但是如果我在其中隐藏一个列表,那么它就不能成为键。.我不能像在模块内部一样轻松地隐藏一个列表吗? 我有一个模糊的想法,认为密钥必须是“可哈希的”,但是我只是承认自己对技术细节的无知。我不知道这里到底发生了什么。如果您尝试使用列表作为键,而将哈希作为其存储位置,那会出什么问题呢? 问题答案: Pyt