2013-12-22 214 views
0

我在我的數據庫上運行了一個查詢,發現了一個奇怪的sql行爲。返回的結果對我來說沒有意義。我已經運行了這個查詢,返回的結果不是我們想要的結果。MySQL查詢返回的意外結果

SELECT MAX(marks), name FROM umer WHERE city!="NewYork" 

這是表格的捕捉。

enter image description here

我得到這個結果:

名稱MAX(標記)

埃裏克·施密特100

不過,我應該得到

麥克風rosoft 100

爲什麼上述結果被返回?

PS:查詢返回正確的結果爲city="NEWYORK"

問候

回答

2
SELECT marks, name 
    FROM umer 
    WHERE city != 'NewYork' 
ORDER BY marks DESC 
    LIMIT 1 

您的查詢是行不通的,因爲MAX(marks)表達和name列沒有它們之間的任何關係。因此mysql完全符合您的要求 - 它會返回marks列的最大值和某些值的name列的最大值。

雖然我的查詢會做:它會返回一個沒有city'NewYork'並具有最大值marks值的行。

+0

那麼,爲什麼我收到了'城市= 「NEWYORK」'正確的結果? – Naruto

+0

@Naruto:因爲它是「第一」行。因此,mysql爲「第一個」行返回'name'(其中「first」通常是如何將行實際存儲在磁盤上) – zerkms

+0

ok,所以相同的邏輯對於'AVG,MIN,COUNT'等其他函數有效 – Naruto

2

由於MySQL Extensions to GROUP BY下記載:

在標準的SQL,包括GROUP BY子句不能引用非聚合列在未在GROUP BY子句中命名的選擇列表中的查詢。例如,因爲在選擇列表中的name列沒有出現在GROUP BY這個查詢是標準的SQL違法:

SELECT o.custid, c.name, MAX(o.payment) 
    FROM orders AS o, customers AS c 
    WHERE o.custid = c.custid 
    GROUP BY o.custid; 

對於查詢是合法的,在name列必須從選擇列表中被省略或在GROUP BY條款中命名。

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

在一般情況下,我們需要使用一個子查詢找到marks最大值,然後用它來獲得最大記錄的其他列:

SELECT * 
FROM  umer 
WHERE marks = (
      SELECT MAX(marks) 
      FROM umer 
      WHERE city != 'NewYork' 
     ) 

或者,使用自聯接:

SELECT * 
FROM  umer NATURAL JOIN (
      SELECT MAX(marks) marks 
      FROM umer 
      WHERE city != 'NewYork' 
     ) t 

上述兩種方法將返回所有記錄有最大標誌。如果你只想要一個這樣的紀錄,您只需將過濾記錄進行排序和限制結果:

SELECT * 
FROM  umer 
WHERE city != 'NewYork' 
ORDER BY marks DESC 
LIMIT 1 

看到他們sqlfiddle

-1

添加ORDER BY在查詢默認ORDER BY監守是ASC, 檢查這個

SELECT MAX(marks), name FROM umer WHERE city!='NewYork' 
ORDER BY marks DESC LIMIT 1 
+0

-1否,'ORDER BY'在結果聚合後生效*,因此對包含單個記錄的結果集有*無效*。請參閱[sqlfiddle](http://sqlfiddle.com/#!2/408fc/1/0)。 – eggyal