2014-02-20 66 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