2009-05-29 139 views
45

我有如下表:選擇3條最近的記錄,其中一列的值是不同的

id  time  text  otheridentifier 
    ------------------------------------------- 
    1  6   apple  4 
    2  7   orange 4 
    3  8   banana 3 
    4  9   pear  3 
    5  10  grape  2 

我想要做的就是選擇3條最近的記錄(按時間倒序),其otheridentifier s是不同的。所以在這種情況下,結果將是id的:5,4,和2

id = 3會被跳過,因爲有與同otheridentifier現場更近的記錄。

這裏就是我試圖做的:

SELECT * FROM `table` GROUP BY (`otheridentifier`) ORDER BY `time` DESC LIMIT 3 

然而,我最終得到的id = 5行,,並而不是5,4,2符合市場預期。

有人可以告訴我爲什麼這個查詢不會返回我的預期?我試圖改變ORDER BY對於ASC但這隻會重新排列返回的行1,3,5

回答

34

它不返回你所期望的,因爲分組訂購之前發生,通過在該條款的位置反映SQL語句。不幸的是你不得不花更多的時間來獲得你想要的行。試試這個:

SELECT * 
FROM `table` 
WHERE `id` = (
    SELECT `id` 
    FROM `table` as `alt` 
    WHERE `alt`.`otheridentifier` = `table`.`otheridentifier` 
    ORDER BY `time` DESC 
    LIMIT 1 
) 
ORDER BY `time` DESC 
LIMIT 3 
+1

我記得我花了很多時間來解決這樣的SQL的時間和原來的MySQL 4.0不支持嵌套查詢,p – Unreality 2009-05-29 05:29:44

+1

@Unreality:Fortu如果需要,大多數涉及子查詢的解決方案都可以表示爲連接。 :) – Rytmis 2009-05-29 05:32:54

+1

是的,但具有ORDER/LIMIT的不容易通過JOIN表示... – 2009-05-29 05:41:37

2
SELECT * FROM table t1 
WHERE t1.time = 
    (SELECT MAX(time) FROM table t2 
    WHERE t2.otheridentifier = t1.otheridentifier) 
18

您可以加入表本身來過濾每otheridentifier最後一個條目,然後取前3排的是:

SELECT last.* 
FROM `table` last 
LEFT JOIN `table` prev 
    ON prev.`otheridentifier` = last.`otheridentifier` 
    AND prev.`time` < last.`time` 
WHERE prev.`id` is null 
ORDER BY last.`time` DESC 
LIMIT 3 
2

Andomar's answer可能是最好的它不使用子查詢。

的另一種方法:

select * 
from `table` t1 
where t1.`time` in (
        select max(s2.`time`) 
        from  `table` t2 
        group by t2.otheridentifier 
        ) 
1

怎麼樣

SELECT *, max(time) FROM `table` group by otheridentifier 
4

我也有類似的要求,但我有更先進的選擇標準。使用一些其他的答案我無法得到我需要的到底是什麼,但我發現你仍然可以做一個GROUP BY之後和ORDER BY這樣的:

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t 
GROUP BY t.otheridentifier 
2

您可以使用此查詢來獲取正確的答案:

SELECT * FROM 
     (SELECT * FROM `table` order by time DESC) 
      t group by otheridentifier 
0

這也:

SELECT * FROM 
OrigTable T INNER JOIN 
( 
SELECT otheridentifier,max(time) AS duration 
FROM T 
GROUP BY otheridentifier) S 
ON S.duration = T.time AND S.otheridentifier = T.otheridentifier. 
相關問題