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

窗口函数实现同their_ids仅取最新值累加及SUM DISTINCT报错解决

PostgreSQL按指定字段去重的窗口累加实现方案

核心思路

  • 先做行级标记:给每个dude_id分组下的相同their_ids标记最新记录,用ROW_NUMBER()按dude_id + their_ids分区,main_date倒序排序,标记为1的就是对应their_ids的最新记录
  • 再做窗口累加:仅将标记为最新记录的how_many、how_much值计入统计,旧记录对应字段取值为0,避免重复统计

实现代码

WITH marked_records AS (
    SELECT
        *,
        -- 标记每个dude_id下相同their_ids的最新记录,is_latest=1即为最新
        ROW_NUMBER() OVER (PARTITION BY dude_id, their_ids ORDER BY main_date DESC) AS is_latest
    FROM some_table
)
SELECT
    dude_id,
    main_date,
    how_many,
    how_much,
    their_ids,
    SUM(CASE WHEN is_latest = 1 THEN how_many ELSE 0 END) OVER (
        PARTITION BY dude_id 
        ORDER BY main_date 
    ) AS count_stuff_EXPECTED,
    SUM(CASE WHEN is_latest = 1 THEN how_much ELSE 0 END) OVER (
        PARTITION BY dude_id 
        ORDER BY main_date 
    ) AS cumulative_sum_EXPECTED
FROM marked_records
ORDER BY dude_id, main_date;

逻辑说明

你之前尝试的SUM(DISTINCT)不可行,一是因为PostgreSQL当前不支持窗口函数中搭配ORDER BY使用DISTINCT参数,二是DISTINCT是对聚合值去重,不是按their_ids维度去重,本身也不符合业务逻辑。
上述方案的核心是通过预标记过滤掉旧的重复their_ids记录的统计贡献:比如同一个dude_id下their_ids为373的记录共有2条,main_date更大的那条is_latest标记为1,更早的那条标记为2。累加时更早的那条贡献值为0,只有最新的那条会被计入总和,刚好符合「相同their_ids仅保留最新值参与统计」的需求。
如果你的业务允许同一个their_ids的旧记录完全不展示,可以在CTE里直接过滤掉is_latest != 1的记录,再做累加会更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:27:00