仅为表中的每个标识符选择最新值

时间:2014-06-04 21:38:32

标签: sql database postgresql select greatest-n-per-group

我有一个看起来像这样的表:

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;

但我希望获得所有标识符的最新值。我怎么能这样做?

4 个答案:

答案 0 :(得分:7)

Postgres中最简单(通常最快)的方法是DISTINCT ON

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

这也会返回一个有序列表 SQLFiddle.
详细信息:
Select first row in each GROUP BY group?

答案 1 :(得分: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一个带有此演示的方形小说。

结果是:

╔════════════╦═══════╦═════════════════════════════════╦════╗
║ 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 ║
╚════════════╩═══════╩═════════════════════════════════╩════╝

答案 2 :(得分:2)

过滤掉除了最新标识符之外的所有内容:

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

答案 3 :(得分:1)

只需加入表格,添加“<”作为连接条件,并使用 right 时间戳为空的结果 - 那么定义的标识符没有更大的项目)

 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