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

PostgreSQL关联两张表时如何查询各项目对应的最新更新日期与进度

错误原因分析

  • 第一种写法:将progress加入了GROUP BY分组字段,同一个项目下不同进度值会被拆分为多个分组,自然会返回多条同一project_id的结果。
  • 第二种写法:首先缺少两张表的project_id关联条件,会产生笛卡尔积导致重复;其次使用rank()窗口函数,若同一个项目同一天存在多条更新记录,所有同日期的记录rank值都为1,也会返回多条结果。

正确查询方案

方案1:使用PostgreSQL专属DISTINCT ON(性能更优)

适合直接按分组取排序后第一条的场景,写法更简洁:

SELECT DISTINCT ON (tpd.project_id)
    tpd.*,
    tpu.date AS latest_update_date,
    tpu.progress AS latest_progress
FROM company.transition_project_details tpd
LEFT JOIN company.transition_project_updates tpu 
    ON tpd.project_id = tpu.project_id 
    AND tpu.company_id = 2
WHERE tpd.company_transition_id = 2
ORDER BY tpd.project_id, tpu.date DESC;

说明:DISTINCT ON (tpd.project_id)会按项目ID去重,仅保留每个项目排序后的第一条记录,按日期倒序排序后第一条就是最新更新。如果不需要保留无更新记录的项目,把LEFT JOIN改成INNER JOIN即可。

方案2:使用窗口函数(兼容性更强)

如果需要更灵活的排序规则,或者要兼容其他SQL语法,可以用ROW_NUMBER代替RANK避免同排名重复:

SELECT 
    tpd.*,
    project_updates.latest_update_date,
    project_updates.latest_progress
FROM company.transition_project_details tpd
LEFT JOIN (
    SELECT 
        project_id,
        date AS latest_update_date,
        progress AS latest_progress,
        ROW_NUMBER() OVER (PARTITION BY project_id ORDER BY date DESC, progress DESC) AS rn
    FROM company.transition_project_updates 
    WHERE company_id = 2
) project_updates 
ON tpd.project_id = project_updates.project_id 
AND project_updates.rn = 1
WHERE tpd.company_transition_id = 2;

说明:ROW_NUMBER会给每个分区内的记录生成唯一的行号,就算同一天有多条更新,也只会返回排序后的第一条,后面加progress DESC是自定义同日期的优先级规则,可根据需求调整。

内容的提问来源于stack exchange,提问作者Lostsoul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:45:03