WHERE子句中的逻辑处理顺序或SQL标准

时间:2014-02-20 11:08:04

标签: sql postgresql select where-clause sql-standards

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

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

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

1 个答案:

答案 0 :(得分:3)

这是SQL标准的规则(相当复杂,因为它涉及到SQL用户可能没有想到的许多细节)。

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

第二个原则是避免含糊不清。这就是作用域规则的来源,它定义了SQL编译器何时知道。

请考虑以下声明:

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

问题是:a a+1引用的是哪个,a列中的列b还是列a(别名为selectselect。根据标准,这是明确的。列别名在定义它们的where子句中是未知的。

这也扩展到select a as b, b as a, a + 1 as d from t where a > 100 子句,它在同一范围内进行评估。考虑相同的例子:

a

where条件引用哪个where?标准是明确的。 select子句不理解select中的列别名。这是因为在where之后select row_number() over (order by a) as seqnum from t where a > 100 被(逻辑上)评估。所以,当你说:

a

返回的值从 100之后的第一个{{1}} 开始。枚举不会先发生,过滤的行会得到过滤掉的序列号。