2014-02-20 143 views
1

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

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

之所以在WHERE子句会产生错误的别名的使用是SELECT语句的真正逻辑处理顺序,或者更确切地说,语法分析问题,也可能是从SQL标准规则?

回答

3

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

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

第二个原则是避免含糊不清。这是范围规则进入的地方,它定义了SQL编译器何时知道什么。

考虑以下语句:

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

的问题是:其a确实a+1指,在表或列b(其别名为a)列aselect。根据标准,这是明确的。在定义它们的select子句中,列别名是未知的。

这也扩展到where子句,它在相同的范围内进行评估。考虑同样的例子:

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

其中a请问where条件是指什么?该标准是明确的。 where子句不理解select中的列别名。这是因为在where之后(逻辑)select被评估。所以,当你说:

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

返回的值开始与第一a 100枚举不先发生,用过滤行越来越被过滤掉的序列号。

+1

我同意戈登。还要在解析时间评估别名,而不是运行时间。难以进入用于命令式/过程式语言的开发人员的一个概念是查询的关系性质。顺序并不重要,引擎病最终会给出最后一个关于如何处理它的最后一个词,例如,如果您要连接两个表并筛选出第一个filterA,filterB或matchAB会发生什么问题?答:引擎不好决定。 – jean