You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让PostgreSQL窗口函数在子分组内返回相同结果?

PostgreSQL查询需求调整问题

数据表

filepathcreated
AAA08/22/A2022-08-22 22:00:00
AAA08/22/A2022-08-22 21:00:00
AAA08/21/A2022-08-21 20:00:00
AAA08/20/A2022-08-20 21:00:00
BBB08/22/B2022-08-22 21:00:00
CCC08/22/C2022-08-22 21:00:00
CCC08/21/C2022-08-21 21:00:00

当前查询语句

WITH ranked_messages AS (
    select file, created, path,
           row_number() OVER (PARTITION BY file ORDER BY created DESC)  AS rating_in_section
    from files
    order by file
)
SELECT path FROM ranked_messages WHERE rating_in_section > 1 group by path order by path desc;

当前结果

path
08/22/A
08/21/C
08/21/A
08/20/A

期望结果

path
08/21/C
08/21/A
08/20/A

中间状态对比

当前中间状态

filepathcreatedrating
AAA08/22/A2022-08-22 22:00:001
AAA08/22/A2022-08-22 21:00:002
AAA08/21/A2022-08-21 20:00:003
AAA08/20/A2022-08-20 21:00:004
BBB08/22/B2022-08-22 21:00:001
CCC08/22/C2022-08-22 21:00:001
CCC08/21/C2022-08-21 21:00:002

需要的中间状态

filepathcreatedrating
AAA08/22/A2022-08-22 22:00:001
AAA08/22/A2022-08-22 21:00:001
AAA08/21/A2022-08-21 20:00:002
AAA08/20/A2022-08-20 21:00:003
BBB08/22/B2022-08-22 21:00:001
CCC08/22/C2022-08-22 21:00:001
CCC08/21/C2022-08-21 21:00:002

解决方案

要实现需求,需调整窗口函数的分区逻辑,改用dense_rank()替代row_number(),让同一file下相同path的记录共享同一排名:

调整后的查询语句

WITH ranked_messages AS (
    SELECT 
        file, 
        created, 
        path,
        dense_rank() OVER (PARTITION BY file ORDER BY MAX(created) OVER (PARTITION BY file, path) DESC) AS rating_in_section
    FROM files
)
SELECT DISTINCT path 
FROM ranked_messages 
WHERE rating_in_section > 1 
ORDER BY path DESC;

逻辑说明

  1. 内层分区计算:MAX(created) OVER (PARTITION BY file, path) 先获取每个file+path组合的最新创建时间,确保同一path的记录拥有相同的时间标识。
  2. 外层排名:用dense_rank()按file分区,以内层得到的最新时间降序排序,这样同一path的记录会被分配相同的排名。
  3. 筛选去重:最后筛选排名大于1的记录,通过DISTINCT去重后得到期望结果。

内容的提问来源于stack exchange,提问作者Юрий Кот

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 10:45:38