在单个sql语句中选择多个最近的值

时间:2013-08-28 19:03:06

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

我有一个表格,其数据看起来像这样:

data_type, value, datetime
World of Warcraft, 500, 2012-12-02
Quake 3, 1500, 2013-12-02
Quake 3, 1400, 2013-02-04
World of Warcraft, 1200, 2013-05-20
Final Fantasy, 100, 2013-02-03
Final Fantasy, 500, 2013-03-05

我想要选择的内容如下:

data_type, value
World of Warcraft, 1200
Quake 3, 1500
Final Fantasy, 500
select  
  most recent value for 'World of Warcraft', 
  most recent value for 'Quake 3', 
  most recent value for 'Final Fantasy'

因此,我在单个语句中获取每个值的最新值,而不是将它们分开。我该怎么做呢?

2 个答案:

答案 0 :(得分:2)

这应该做:

SELECT *
FROM (  SELECT  *, 
                ROW_NUMBER() OVER(PARTITION BY data_type 
                                  ORDER BY datetimecol DESC) AS RN
        FROM YourTable) AS A
WHERE RN = 1

Postgresql上实际上有一个函数last_value,但我不熟悉它。

如果您希望数据显示在列中,则可以使用:

SELECT 
    max(case when data_type='World of Warcraft' then value end) WorldofWarcraft,
    max(case when data_type='Quake 3' then value end) Quake3,
    max(case when data_type='Final Fantasy' then value end) FinalFantasy
FROM (  SELECT  data_type, value, datetime, 
                ROW_NUMBER() OVER(PARTITION BY data_type 
                                  ORDER BY datetimecol DESC) AS RN
        FROM YourTable) AS A
WHERE RN = 1

答案 1 :(得分:0)

DISTINCT ON 的另一种情况。更简单,更快捷:

SELECT DISTINCT ON (data_type)
       data_type, value
FROM   tbl
ORDER  BY data_type DESC, datetime DESC;

您可以包含或排除任何您喜欢的列。更多解释和细节:
Select first row in each GROUP BY group?

我使用data_type DESC ,因为您的示例表明您希望降序为您的数据类型。如果你不在乎,请省略DESC

您还应该规范化您的数据。为您的数据类型创建一个查找表,并仅将外键存储在主表中。 Example.