查找最新的不同记录,并按Postgresql中的created_at排序

时间:2014-10-21 12:43:29

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

我认为找到解决方案非常容易,但我找不到与我尝试做的相符的问题。

这是我想看到的内容(此查询不起作用):

SELECT DISTINCT ON (conversation_id) 
  *
FROM messages
ORDER BY created_at DESC

换句话说,返回具有最新created_at日期的完整行,其中conversation_id是不同的,然后按created_at DESC排序。

我在下面写了一个查询,它正是我正在寻找的,但我认为我过于复杂了。我还假设最新的记录具有最高的ID,并且在子查询中按其排序,而不是" created_at" (它返回与created_at DESC相同的顺序,但读者友好程度较低)。

SELECT 
  m.*
FROM (
  SELECT 
    DISTINCT ON (conversation_id) conversation_id,
    id
  FROM messages
  ORDER BY conversation_id, id DESC
) as t
INNER JOIN messages as m
  ON t.id = m.id
ORDER BY t.id DESC

制作此查询的更简单版本的任何帮助都会很棒。


为澄清添加了示例

如果消息表如下所示:

id, conversation_id, created_at, subject
1, 2,  "2014-10-21 00:01:00", "subject 1"
2, 43, "2014-10-21 00:02:00", "subject 2"
3, 12, "2014-10-21 00:03:00", "subject 3"
4, 2,  "2014-10-21 00:04:00", "subject 4"
5, 43, "2014-10-21 00:05:00", "subject 5"

查询应返回以下内容:

id, conversation_id, created_at, subject
5, 43, "2014-10-21 00:05:00", "subject 5"
4, 2,  "2014-10-21 00:04:00", "subject 4"
3, 12, "2014-10-21 00:03:00", "subject 3"

2 个答案:

答案 0 :(得分:4)

不需要加入:

select *
from (
    select distinct on (conversation_id) *
    from messages
    order by conversation_id, id desc
) t
order by id desc

答案 1 :(得分:0)

documentation

  

DISTINCT ON表达式必须与最左边的ORDER BY表达式匹配。 ORDER BY子句通常包含其他表达式,用于确定每个DISTINCT中行的所需优先级ON小组。

因此,如果您使用DISTINCT ON (conversation_id),则应使用相同的列启动ORDER BY子句。