PostgreSQL:无需GROUP BY实现按组内最新时间排序且将同一对象事件归组
简洁实现:按对象最晚事件日期分组排序
你提到的这种「先按组的整体最晚时间排序,组内再按个体时间排序」的需求确实在报表场景里很常见,完全不需要复杂的CTE关联,用窗口函数就能轻松搞定。
需求回顾
你需要的排序规则是:
- 所有属于同一
object_id的事件必须归为一组 - 组的排序依据是该组内最晚的
event_date,最晚的组排在最前 - 组内的事件按自身
event_date排序
示例数据:
| event_id | event_date | object_id |
|---|---|---|
| 11 | 2021-03-01 | 3 |
| 12 | 2021-02-01 | 3 |
| 13 | 2018-01-01 | 3 |
| 21 | 2021-02-20 | 2 |
| 22 | 2019-10-22 | 2 |
| 31 | 2021-01-30 | 1 |
解决方案代码
利用MAX() OVER (PARTITION BY object_id)窗口函数,直接获取每个对象的最晚事件日期,将其作为第一排序条件即可:
with tbl(event_id, event_date, object_id) as (values (11, date '2021-03-01', 3), (12, date '2021-02-01', 3), (13, date '2018-01-01', 3), (21, date '2021-02-20', 2), (22, date '2019-10-22', 2), (31, date '2021-01-30', 1)) select * from tbl order by -- 按每个对象的最晚事件日期降序,实现分组排序 max(event_date) over (partition by object_id) desc, -- 可选:如果多个对象有相同的最晚日期,用object_id保证排序稳定 object_id, -- 组内按事件自身日期排序 event_date;
排序逻辑拆解
max(event_date) over (partition by object_id) desc:这一步是核心,它会为每条记录计算出所属对象的最晚事件日期,以此作为第一排序键,就能让同一对象的所有事件聚集在一起,且最晚的对象组排在最前面object_id:作为兜底的排序条件,避免当多个对象的最晚事件日期相同时,分组出现混乱event_date:组内的事件按自身发生日期排序,你可以根据需求改成desc实现倒序
内容的提问来源于stack exchange,提问作者gavenkoa
相关产品推荐
相关产品推荐

