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

如何在单条SQL中实现按去重ID求和(Analytical Function SUM with Distinct)

解决方案

完全可以在单条SQL中实现该需求,无需拆分成分步查询,核心逻辑是先按ID对源数据去重,再基于去重后的结果执行求和运算即可。

你原来的查询没有做去重处理,直接求和会把重复ID的金额也计入,最终得到的总和是23,不符合预期。以下是两种可行的实现写法:

写法1:直接统计去重后的总金额

WITH data AS
(
    SELECT 1 AS ID ,'ABC' AS Name, 'Paid' AS Status, 10 AS Amount
    UNION ALL
    SELECT 1 AS ID ,'ABC' AS Name, 'Paid' AS Status, 10 AS Amount
    UNION ALL
    SELECT 2 AS ID ,'ABC' AS Name, 'Paid' AS Status, 1 AS Amount
    UNION ALL
    SELECT 3 AS ID ,'ABC' AS Name, 'Paid' AS Status, 1 AS Amount
    UNION ALL
    SELECT 4 AS ID ,'ABC' AS Name, 'Paid' AS Status, 1 AS Amount
)
SELECT SUM(Amount) AS total_amount
FROM (
    -- 内层查询先完成ID去重
    SELECT DISTINCT ID, Amount, Name, Status
    FROM data
) t

运行后得到的total_amount结果为13,符合预期。

写法2:保留窗口函数逻辑,先去重再开窗

如果你需要保留每行明细+分组求和的结果格式,可以嵌套一层CTE做去重:

WITH data AS
(
    SELECT 1 AS ID ,'ABC' AS Name, 'Paid' AS Status, 10 AS Amount
    UNION ALL
    SELECT 1 AS ID ,'ABC' AS Name, 'Paid' AS Status, 10 AS Amount
    UNION ALL
    SELECT 2 AS ID ,'ABC' AS Name, 'Paid' AS Status, 1 AS Amount
    UNION ALL
    SELECT 3 AS ID ,'ABC' AS Name, 'Paid' AS Status, 1 AS Amount
    UNION ALL
    SELECT 4 AS ID ,'ABC' AS Name, 'Paid' AS Status, 1 AS Amount
),
deduplicated_data AS (
    -- 按ID去重,同一个ID只保留1条记录
    SELECT DISTINCT ID, Name, Status, Amount FROM data
)
SELECT *, SUM(Amount) OVER (PARTITION BY Name, Status) AS total_amount
FROM deduplicated_data

扩展说明

如果存在同一个ID对应的其他字段(Name/Status/Amount)不一致的场景,可以改用ROW_NUMBER()函数自定义去重规则,比如每个ID只取第一条记录:

deduplicated_data AS (
    SELECT * FROM (
        SELECT *,
        ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) AS rn
        FROM data
    ) t WHERE rn = 1
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:15:07