如何按type分组时对每个唯一idParent的val仅求和一次?
问题:关联父子表按type分组时,每个父ID的val仅求和一次
数据结构
父表(Parent table)
| idParent | val |
|---|---|
| 1 | 12 |
子表(Child table)
| idChild | idParent | type |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 1 | 2 |
当前查询及问题
当前使用的查询语句:
select c.type, sum(p.val) from parent as p join child as c on p.idParent = c.idParent group by c.type
返回结果:
| type | sum |
|---|---|
| 1 | 24 |
| 2 | 12 |
该结果不符合预期:type=1的分组中,同一idParent的val被重复计算了两次。需求是每个唯一的idParent在对应type分组中仅被计算一次val。
预期输出
| type | sum |
|---|---|
| 1 | 12 |
| 2 | 12 |
补充测试数据及预期
针对不同父表val值相同的场景,补充数据如下:
父表
| idParent | val |
|---|---|
| 1 | 12 |
| 2 | 12 |
| 3 | 34 |
| 4 | 45 |
| 5 | 56 |
子表
| idChild | idParent | type |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 1 | 2 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 3 | 1 |
| 7 | 3 | 2 |
| 8 | 3 | 2 |
| 9 | 4 | 1 |
| 10 | 5 | 2 |
预期结果
| type | sum |
|---|---|
| 1 | 103 |
| 2 | 114 |
原因说明
- type=1对应的父ID为1、2、3、4,每个父ID仅计算一次val,求和为
12+12+34+45=103 - type=2对应的父ID为1、2、3、5,每个父ID仅计算一次val,求和为
12+12+34+56=114
需求强调
对val字段求和时,每个idParent仅被计算一次,即便同一idParent对应多条同type的子表记录,也仅计入一次该父表的val值。希望尽量保留原有SQL结构,不使用CTE、派生表,仅修改字段部分。
解决方案
要实现每个idParent在对应type分组中仅被计算一次val,核心是先确保每个(idParent, type)组合唯一,再关联父表求和。以下是两种可行方式:
方式1:去重子查询(逻辑清晰,接近原有结构)
select c.type, sum(p.val) as sum_val from parent as p join (select distinct idParent, type from child) as c on p.idParent = c.idParent group by c.type
通过子查询先提取每个type下唯一的idParent列表,再关联父表求和,完全符合需求,且结果准确。
方式2:窗口函数标记唯一记录
通过窗口函数标记每个(idParent, type)的第一条记录,仅对该记录的val求和:
select c.type, sum(case when rn = 1 then p.val else 0 end) as sum_val from parent as p join ( select idParent, type, row_number() over (partition by idParent, type order by idChild) as rn from child ) as c on p.idParent = c.idParent group by c.type
注意事项
不要使用SUM(DISTINCT p.val),因为当不同idParent的val值相同时,会错误地合并这些值,导致求和结果不准确。
内容的提问来源于stack exchange,提问作者Rand Random
相关产品推荐
相关产品推荐

