幾天前我被問到關於SELECT語句的邏輯處理順序,更具體地說是關於別名和where子句,我不確定關於一個問題。如果我們有這樣一個查詢:WHERE子句中的邏輯處理順序或SQL標準
SELECT name AS first_name
FROM people
WHERE first_name = 'Alan';
之所以在WHERE子句會產生錯誤的別名的使用是SELECT語句的真正邏輯處理順序,或者更確切地說,語法分析問題,也可能是從SQL標準規則?
幾天前我被問到關於SELECT語句的邏輯處理順序,更具體地說是關於別名和where子句,我不確定關於一個問題。如果我們有這樣一個查詢:WHERE子句中的邏輯處理順序或SQL標準
SELECT name AS first_name
FROM people
WHERE first_name = 'Alan';
之所以在WHERE子句會產生錯誤的別名的使用是SELECT語句的真正邏輯處理順序,或者更確切地說,語法分析問題,也可能是從SQL標準規則?
這是來自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
)列a
在select
。根據標準,這是明確的。在定義它們的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枚舉不先發生,用過濾行越來越被過濾掉的序列號。
我同意戈登。還要在解析時間評估別名,而不是運行時間。難以進入用於命令式/過程式語言的開發人員的一個概念是查詢的關係性質。順序並不重要,引擎病最終會給出最後一個關於如何處理它的最後一個詞,例如,如果您要連接兩個表並篩選出第一個filterA,filterB或matchAB會發生什麼問題?答:引擎不好決定。 – jean