2014-02-22 20 views
2

我想知道組的工作查詢爲什麼沒有「標記<MAX(商標)」工作

假設有一個表的學生(ID,姓名,標記)

現在,如果我想輸出除那些/誰得分最高的所有學生,爲什麼這個查詢不起作用?

SELECT * FROM Students 
WHERE marks < MAX(marks) 

但能正常工作

SELECT * FROM Students 
WHERE marks < (SELECT MAX(marks) FROM Students) 

編輯: 請不要建議不同的方法來解決這一問題,我已經知道。 我的問題是爲什麼這不起作用,請看看標題密切

+0

使用HAVING而不是WHERE。您需要後期彙總過濾。 –

+0

你爲什麼試圖列出所有沒有最高分的學生? (即通常除了一個或者兩個的所有類) –

+0

居然有人問我獲得第二個最高分, 所以我嘗試 SELECT * FROM學生 WHERE標記 Harry

回答

5

簡短的答案是,這就是SQL的設計。更長的回答要求我們看看你的第一個查詢意味着什麼,以及爲什麼最終不太合理。

可以想象一個SQL,您可以將整個表的聚合與行值進行比較。但是,如果您有GROUP BY?您的MAX會適用於整個桌面還是僅適用於該組?如果你想讓它反對不同的分組,或者整個桌子而不是整個團隊呢?

現在讓我們從底層操作的角度來思考它。爲了實際計算行值和最大值,數據庫引擎必須執行兩項操作:一項用於查找最大值,另一項用於掃描表,將值與此計算的最大值進行比較。但是,在WHERE子句中,如果沒有子查詢,則只是逐行比較列中的值。添加聚合是一種不同類型的數據,不能通過逐行查看值來收集。

另一種看待它的方法是:聚合發生在GROUP BY之後(即使GROUP BY是隱含的)。但WHERE子句在GROUP BY之前執行。所以它無法訪問聚合。

由於所有這些原因,並且可能更多,SQL被設計爲在比較不同類型的值時強制您明確表示。你必須告訴它你明確地計算了最大值,然後用它來比較行值。這是通過子查詢完成的。

+0

謝謝,完美的解釋。 +1 – Harry

+1

還有另一種看待它的方式:WHERE條款的行爲就像它們對每一行分別進行評估一樣。在這種情況下,MAX(marks)是單個值的最大值(該行的「marks」的值!),所以條件從不爲真。 – duskwuff