1

几天前有人问我关于 SELECT 语句的逻辑处理顺序,更具体地说是关于别名和 where 子句,我不确定一个问题。如果我们有这样的查询:

SELECT name AS first_name
FROM people
WHERE first_name = 'Alan';

在 WHERE 子句中使用别名会产生错误的原因实际上是 SELECT 语句的逻辑处理顺序,或者更确切地说是语法解析问题,或者可能是 SQL 标准的规则?

4

1 回答 1

3

这是来自 SQL 标准的规则(这相当复杂,因为它涉及到许多 SQL 用户可能不会考虑的细节)。

该规则背后有两个原则。首先是该标准不强加操作的顺序,除非在逻辑上必要时(having例如,一个子句必须在 a 之后进行逻辑处理group by)。这是 SQL 概念的基础,它是一种描述性语言,其中描述了结果。任何特定的数据库引擎都可以确定自己的执行路径。

第二个原则是避免歧义。这就是作用域规则的用武之地,它定义了 SQL 编译器何时知道什么。

考虑以下语句:

select a as b, b as a, a + 1 as d
-----------------------^
from t

问题是:哪个a确实a+1指的是表中的a列或. 根据标准,这是明确的。列别名在定义它们的子句中是未知的。baselectselect

这也延伸到where在相同范围内评估的子句。考虑同样的例子:

select a as b, b as a, a + 1 as d
from t
where a > 100

条件指的是哪个awhere标准是明确的。该where子句不理解select. 这是因为select是(逻辑上)在 之后评估的where。所以,当你说:

select row_number() over (order by a) as seqnum
from t
where a > 100

返回的值从100a 之后的第一个开始。枚举不会首先发生,过滤的行获得被过滤掉的序列号。

于 2014-02-20T12:05:17.763 回答