在 Postgresql 中查找最近的不同记录并按 created_at 排序

Posted

技术标签:

【中文标题】在 Postgresql 中查找最近的不同记录并按 created_at 排序【英文标题】:Find most recent distinct records and sort by created_at in Postgresql 【发布时间】:2014-12-16 16:46:18 【问题描述】:

我认为这很容易找到解决方案,但我找不到与我正在尝试做的事情相匹配的问题。

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

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"

【问题讨论】:

【参考方案1】:

不需要加入:

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

【讨论】:

【参考方案2】:

每documentation:

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

所以如果你使用DISTINCT ON (conversation_id),你应该在同一列开始ORDER BY子句。

【讨论】:

感谢您的意见,但我已经知道了。我要问的是,“有没有比我上面的问题中的第二个查询更简单的解决方案。” 你想按conversation_id分区,按created_at排序,然后选择rank postgresql.org/docs/current/static/tutorial-window.html @newUserNameHere,不清楚你想要什么。第一个查询使用ORDER BY created_at,第二个查询——不是。 在那个链接中查看这个查询。 SELECT depname,empno,salary,enroll_date FROM (SELECT depname,empno,salary,enroll_date,rank() OVER (PARTITION BY depname ORDER BY Salary DESC,empno) AS pos FROM empsalary )AS ss WHERE pos @vyegorov,我更新了问题以使其更易于理解并添加了一个示例。在子查询中按 ID 排序与按创建时间排序的效果相同,因为 created_at 日期最高的消息也具有较大的 ID。这在示例中最为明显。希望这是有道理的。

以上是关于在 Postgresql 中查找最近的不同记录并按 created_at 排序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PostgreSQL 中查找重复记录

如何在 postgresql 中进行查询,以查找所有启动时间超过 6 小时的记录?

PostgreSQL 如何查找并删除重复数据

PostgreSQL 如何查找并删除重复数据

PostgreSQL 如何查找并删除重复数据

略微复杂的sql逻辑(从数据库逆序查找有限条记录(limit))并按相反顺序输出