2012-08-15 167 views
1

考慮這兩個查詢:爲什麼在還爲列返回MAX值時始終返回最低ID行?

SELECT *, MAX(age) AS maxAge FROM someTable ORDER BY age ASC; 
SELECT *, 'dummyC' AS dummyC FROM someTable ORDER BY age ASC; 

前者查詢返回的所有行和表的所有列,加上額外的虛擬列。後面的查詢只返回一行,即具有最低主鍵的那一行。爲什麼是這樣,我該如何解決它?在一些舊的但穩定的Debian服務器上測試MySQL 5.1。

+1

難道你沒有'前'和'後者'顛倒嗎? – tdammers 2012-08-15 21:49:51

回答

3

這是一個MySQL extension一樣,這是有用的。

MySQL擴展了GROUP BY的用法,以便選擇列表可以引用未在GROUP BY子句中指定的非聚合列。這意味着前面的查詢在MySQL中是合法的。您可以使用此功能通過避免不必要的列排序和分組來獲得更好的性能。但是,這非常有用,因爲每個未在GROUP BY中命名的非聚合列中的所有值對於每個組都是相同的。服務器可以自由選擇每個組中的任何值,因此除非它們相同,否則所選值是不確定的。此外,每個組的值的選擇不能通過添加ORDER BY子句來影響。結果集的排序在選擇值後發生,而ORDER BY不影響服務器選擇的值。

您得到的值是不確定的。您經常會得到插入表中的第一行,但這不能保證。

如果你想從該行包含的最高年齡那麼最好是使用的ORDER BYLIMIT 1組合對應的值:

SELECT * 
FROM someTable 
ORDER BY age DESC 
LIMIT 1; 
+0

謝謝馬克。假設我需要包含最低年齡的行中的值,但也需要最高年齡的值,那麼我將如何獲得該信息是單個查詢? [我問這是一個單獨的問題](http://stackoverflow.com/questions/11982629/how-to-query-row-with-lowest-value-and-also-to-know-the-value-of -the-最高-VA)。 – dotancohen 2012-08-16 07:37:07

1

在第一個查詢中,*是hidden columns

引述MySQL文檔:

MySQL的擴展使用GROUP BY的,這樣的選擇列表可參考 在GROUP BY子句中未命名的非聚合列。這意味着 前面的查詢在MySQL中是合法的。您可以使用此功能 以避免不必要的列排序和 分組以獲得更好的性能。然而,當主要在GROUP BY沒有命名每個 非聚合列中的所有值對每個 組

2

第一個查詢具有聚合函數(MAX),但沒有GROUP BY,這意味着它在整個結果集上進行聚合(收集和合並值),並將其作爲一行返回。大多數SQL方言不允許非聚合列在這樣的查詢中出現,但MySQL專門允許它。但是,這些非聚合列由來自MySQL遇到的第一行的值填充,可能是任何行。如果您從來沒有從相關表中刪除,MySQL通常會首先查找ID最低的行,因爲它以與存儲在磁盤上相同的順序掃描表(至少在需要全表掃描時)。如果您要在桌面上運行一堆DELETE和後續的INSERT語句,您至少會在某些查詢中獲得其他行。總之,不要指望得到任何特定的行。

第二個查詢缺少聚集函數,因此它不執行任何隱式分組 - 您只需獲取完整的結果集。

相關問題