2014-02-10 27 views
0

例如,在有條件的選擇,我有一個表:SQL分組:每組

Name , Area, Age 
cat , 1 , 10 
dog , 2 ,  7 
cat , 3 , 11 
horse , 4 ,  4 
cat , 5 , 10 
dog , 6 ,  9 

當我按「名稱」,每個組我想保留的MAX「時代的「區域」 '在那個組裏。在這個例子中,我想得到:

Name , Area 
cat , 3 
dog , 6 
horse, 4 

我應該如何在一個查詢中做到這一點?多謝你們!

+0

@SamD我不需要最大年齡,我想每個組的最大年齡的'面積'。在您的查詢中,「區域」是從每個組中隨機選擇的。 – xiaolong

+0

@SamD該查詢無法按預期工作。該地區將是隨機的。 –

回答

1

嘗試這樣:

SELECT name, area FROM mytable 
JOIN (
    SELECT name, MAX(age) as maxage FROM mytable 
    GROUP BY name 
) AS `max` 
ON mytable.name = max.name AND mytable.age = max.maxage 

這首先選擇一個子查詢的nameMAX(age),然後將它們加入到原始表,這樣就可以得到與MAX(age)相關的area。通過使用joininner join,我們確保原始表中沒有任何匹配的任何結果不會顯示。

注意,你不能這樣做:

SELECT name, MAX(age), area FROM mytable 

因爲area將從該組中所有的area值隨機選擇。它不知道你想要哪個area。你可能會認爲它會讓areaMAX(age)在同一行,但它不會。它實際上並不知道這就是你想要的。

+0

工作得很好。 thx .. – xiaolong

0

看來我需要學會更快地鍵入=)

不管怎樣,我想出了這一點;你可以測試它in this sqlFiddle

SELECT t.Name, t.Area 
    FROM (SELECT Name, Max(Age) as Max_Age 
      FROM test 
     GROUP BY Name) mx 
    JOIN test t 
    ON t.Name = mx.Name 
    AND t.Age = mx.Max_Age 
ORDER BY t.Name 
+0

謝謝,這與@ DamienBlack的查詢差不多。工作得很好。 – xiaolong

+0

是的,它幾乎是一樣的,但至少他解釋了它的作用,並鍵入更快=)。 然後,我有一個sqlFiddle = P。無論如何,請將PinnyM的評論納入考慮範圍。它現在可能在100條記錄上效果很好,但是一旦你用一堆記錄進入生產幾個月,就會引起頭痛。 – deroby

2

這將是更稍微比@deroby和@DamienBlack提到的子查詢的方法更有效:

SELECT t1.name, t1.area 
FROM myTable t1 
LEFT JOIN myTable t2 
    ON t1.name = t2.name AND t2.Age > t1.Age 
WHERE t2.some_primary_key IS NULL 
ORDER BY t1.name 

注意,這需要已知含有值一些列不是NULL(如主鍵)。您可以根據需要用t2.some_primary_key替換任何其他非空索引列。

SQLFiddle based off @ deroby's here

+0

雖然MSSQL(++)上的執行計劃似乎與您一致,但此查詢的結果並不完全正確(尚未)。 [++:不是線索如何比較這在mysql] – deroby

+0

@deroby - 我的部分小錯誤 - 再次檢查。 – PinnyM

+0

這也是一個聰明的解決方案。我想知道性能差異是什麼。 –