大家好,我是欧阳方超,公众号同名。

1 概述
在一次分组查询时发生了这样一个问题,第一次分组后对结果进行了计数操作,之后在代码层面又对结果集进行了一次计数操作,然后进行求和,结果呢所求的和就包含了重复数据,所以有时候分组之后依然需要每组内的明细数据。本次就记录下如何解决这个问题。
2 问题描述与分析
上面的描述有些抽象,下面通过一个简单的示例解释一下。
| case_id | level_code | case_type | org_id |
|---|---|---|---|
| 1 | 00010001 | 1 | 1 |
| 2 | 000100010001 | 1 | 2 |
| 3 | 000100010002 | 1 | 3 |
| 4 | 000100010002 | 2 | 3 |
假如level_code的前8位相同的为同一个范围内的机构,先按照SUBSTRING(level_code FROM 1 FOR 8)与case_type分组,第一组level_code与case_type分别为00010001、1,组内有三个机构,org_id分别为1、2、3,第二组level_code与case_type分别为00010001、2,组内有一个机构,org_id为3,如果这两组数据再按照level_code的前8位分组,那么两组数据会归为一组,机构数如果相加的话是4,而实际机构只有3加,因此这种情况下在分组时需要保留明细数据,可以考虑使用array_agg函数,
select
SUBSTRING(level_code FROM 1 FOR 8),
case_type,
array_agg(org_id) orgIds
from c_case
这样在第二次聚合数据时,可以将明细数据进行合并,然后去重,进而得到有效的机构数。
注意,如果使用了MyBatis这样的框架,可以使用String类型的属性接收orgIds,然后再转换为数组或列表进行去重计算。
3 总结
本文分析了分组查询中重复计数导致统计结果不准确的问题。在实际操作里,当对数据进行第一次分组并计数后,若在代码层面再次计数求和,会使结果包含重复数据。通过一个具体示例,展示了在 c_case 表中按 level_code 前 8 位和 case_type 分组,若后续再次按 level_code 前 8 位分组时简单相加机构数会出现统计错误。为解决该问题,建议使用 array_agg 函数在分组时保留明细数据,如此在第二次聚合数据时,可将明细数据合并并去重,从而得到准确的机构数。此外,对于使用 MyBatis 框架的情况,可先用 String 类型属性接收 orgIds,再转换为数组或列表进行去重计算。
我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。我们下次见。
使用array_agg解决PostgreSQL分组重复计数
7365

被折叠的 条评论
为什么被折叠?



