2014-06-04 41 views
4

我有一個表,看起來像這樣:在表中只選擇每個標識符中的最新值

identifier | value | tstamp 
-----------+-------+--------------------- 
abc  | 21 | 2014-01-05 05:24:31 
xyz  | 16 | 2014-01-11 03:32:04 
sdf  | 11 | 2014-02-06 07:04:24 
qwe  | 24 | 2014-02-14 02:12:07 
abc  | 23 | 2014-02-17 08:45:24 
sdf  | 15 | 2014-03-21 11:23:17 
xyz  | 19 | 2014-03-27 09:52:37 

我知道如何獲取最新的值一個標識符:

select * from table where identifier = 'abc' order by tstamp desc limit 1; 

但我想獲得所有標識符的最新值。我怎樣才能做到這一點?

回答

6

最簡單的(而且往往最快)的方法是在Postgres的DISTINCT ON

SELECT DISTINCT ON (identifier) * 
FROM tbl 
ORDER BY identifier, tstamp DESC; 

這也返回一個有序列表。
SQLFiddle.
詳情:
Select first row in each GROUP BY group?

+0

謝謝,我選擇了你的答案。它的工作原理是根據「解釋分析」最快的。 – BLuFeNiX

+2

+1,我不知道postgres中的DISTINCT ON() – Lamak

2

篩選出來的一切,但像這樣的最新標識:

select * from table t 
where not exists 
    (SELECT 1 
     FROM table x 
     WHERE x.identifier = t.identifier 
     AND x.tstamp > t.tstamp 
    ) ; 
+0

我不知道這是什麼是應該做的;我想你可能誤解了我的問題。不過謝謝! – BLuFeNiX

+0

@BLuFeNiX查詢無誤(現在,在編輯之後)。這是解決問題的有效方法。 –

+0

當我最初發布時,我忘記了包含x.identifier = t.identifier。感謝您修復@ypercube – comfortablydrei

5
SELECT * 
FROM ( SELECT *, 
       ROW_NUMBER() OVER(PARTITION BY identifier 
            ORDER BY tstamp DESC) AS RN 
     FROM YourTable) AS T 
WHERE RN = 1 

Here is與此演示的sqlfiddle。

的結果是:

╔════════════╦═══════╦═════════════════════════════════╦════╗ 
║ IDENTIFIER ║ VALUE ║    TSTAMP    ║ RN ║ 
╠════════════╬═══════╬═════════════════════════════════╬════╣ 
║ abc  ║ 23 ║ February, 17 2014 08:45:24+0000 ║ 1 ║ 
║ qwe  ║ 24 ║ February, 14 2014 02:12:07+0000 ║ 1 ║ 
║ sdf  ║ 15 ║ March, 21 2014 11:23:17+0000 ║ 1 ║ 
║ xyz  ║ 19 ║ March, 27 2014 09:52:37+0000 ║ 1 ║ 
╚════════════╩═══════╩═════════════════════════════════╩════╝ 
+0

謝謝!與「DISTINCT ON」答案相比,這種方法有什麼好處嗎? – BLuFeNiX

+0

@BLuFeNiX我實際上不知道postgres中的'DISTINCT ON',所以我無法真正比​​較這兩種方法。 – Lamak

+2

@BLuFeNiX:一個好處是,窗口函數可以在所有現代RDBMS(除MySQL以外)中使用,而「DISTINCT ON」是標準SQL「DISTINCT」子句的Postgres特定擴展。 –

1

只需使用自己加入表,加入「<」作爲連接條件,並將結果在時間戳爲空 - 那麼就沒有大項目爲所定義的標識符)

SELECT t1.* FROM tbl t1 
    LEFT JOIN tbl t2 
    ON t1.identifier = t2.identifier AND 
    t1.tstamp < t2.tstamp 
    WHERE t2.tstamp is null 

被盜小提琴: http://sqlfiddle.com/#!15/39e7a/4

+0

謝謝!與「DISTINCT ON」答案相比,這種方法有什麼好處嗎? – BLuFeNiX