SQL分组求和后重复行问题:合并同OrderId的结果行
解决订单转账金额汇总重复行问题
问题背景
现有Orders和Transfers两张表,需要对存在多笔转账的订单汇总总金额。当前使用窗口函数的SQL计算金额正确,但返回重复行,期望仅显示一行订单的汇总结果。
表结构
Orders表
| OrderId | CustomerId |
|---|---|
| Order_1 | Customer_1 |
Transfers表
| TransferID | Amount | OrderId |
|---|---|---|
| Transfer_1 | 5 | Order_1 |
| Transfer_2 | 5 | Order_1 |
当前SQL及问题
Select OrderId, CustomerId, SUM(Amount) over (partition by O.OrderId) AS Amount FROM Orders O LEFT JOIN Transfers T ON O.OrderId = T.OrderId
- 预期结果:
| OrderId | CustomerId | Amount |
|---|---|---|
| Order_1 | Customer_1 | 10 |
- 实际结果:
| OrderId | CustomerId | Amount |
|---|---|---|
| Order_1 | Customer_1 | 10 |
| Order_1 | Customer_1 | 10 |
问题原因:LEFT JOIN后,订单对应的每笔转账都会生成一条记录,窗口函数SUM(Amount) OVER (PARTITION BY O.OrderId)会给每条记录都计算该订单的总金额,导致结果行数和转账记录数一致,出现重复。
解决方案
方案1:使用DISTINCT去重
直接在SELECT语句中添加DISTINCT关键字,去除完全重复的结果行:
SELECT DISTINCT O.OrderId, O.CustomerId, SUM(T.Amount) OVER (PARTITION BY O.OrderId) AS Amount FROM Orders O LEFT JOIN Transfers T ON O.OrderId = T.OrderId
方案2:先聚合转账表再关联(推荐,性能更优)
先在子查询中按OrderId汇总转账金额,再和Orders表关联,避免生成重复行:
SELECT O.OrderId, O.CustomerId, COALESCE(T.TotalAmount, 0) AS Amount FROM Orders O LEFT JOIN ( SELECT OrderId, SUM(Amount) AS TotalAmount FROM Transfers GROUP BY OrderId ) T ON O.OrderId = T.OrderId
注:COALESCE用于处理无转账记录的订单,将金额设为0,可根据需求调整。
方案3:使用GROUP BY分组聚合
直接按订单字段分组,聚合计算总金额:
SELECT O.OrderId, O.CustomerId, SUM(T.Amount) AS Amount FROM Orders O LEFT JOIN Transfers T ON O.OrderId = T.OrderId GROUP BY O.OrderId, O.CustomerId
内容的提问来源于stack exchange,提问作者DearDeer
相关产品推荐
相关产品推荐

