SQL查询PMV险类保单年保费与理赔数时出现保单号重复问题
问题根因
- 保单号重复的核心原因:
AcctMon_Cover_Class_Live_Basic表不是单保单粒度的表,同一个UnderWriting_Ref_UWRF保单号下存在多条对应不同保障项的记录,每条记录对应独立的Annual_Premium_APRM值。你的GROUP BY字段包含了Annual_Premium_APRM,会将同一保单的多条保费记录拆分为独立分组,最终返回重复的保单号。 - 理赔计数不准的核心原因:直接左连接两张原表会产生笛卡尔积膨胀——当同一保单在cclb表有N条记录、在理赔表有M条记录时,连接后会生成N*M行数据,此时直接COUNT理赔号会得到虚高、且分组间不一致的错误值,和你样例中同一保单ClaimAmount出现4、2、2多个异常值的表现完全吻合。
- 细节冗余:
like 'pmv'在无通配符时等价于精确匹配,直接写= 'PMV'可读性更好,也能规避部分数据库大小写校验规则导致的匹配遗漏问题。
修正方案
核心思路是先将两张表分别聚合到保单粒度,保证关联时每个保单号在左右表都只有1条记录,从根源避免连接行膨胀,最终实现每个保单号仅返回1行统计结果。
修正后的SQL语句如下:
SELECT cclb.UnderWriting_Ref_UWRF, cclb.Cover_Class_CVCL, cclb.Total_Annual_Premium, COALESCE(csm.Claim_Count, 0) AS Claim_Count FROM ( -- 先聚合保单基础表:按保单号分组,汇总该保单总年保费,保证每个PMV类保单仅1行 SELECT UnderWriting_Ref_UWRF, Cover_Class_CVCL, SUM(Annual_Premium_APRM) AS Total_Annual_Premium FROM Sandbox.DataTeam_Resources_Arc202512.AcctMon_Cover_Class_Live_Basic WHERE Cover_Class_CVCL = 'PMV' GROUP BY UnderWriting_Ref_UWRF, Cover_Class_CVCL ) cclb LEFT JOIN ( -- 先聚合理赔表:按保单号分组统计理赔总数,保证每个保单仅1行 SELECT Underwriting_Ref_UWRF, COUNT(claim_ref_CMRF) AS Claim_Count FROM Sandbox.DataTeam_AcctMonitoring_Arc202512.C_ClaimSummary_Merged GROUP BY Underwriting_Ref_UWRF ) csm ON csm.Underwriting_Ref_UWRF = cclb.UnderWriting_Ref_UWRF ORDER BY cclb.UnderWriting_Ref_UWRF ASC;
如果你不需要汇总年保费,需要保留同一保单下的多条保费明细,同时要在每条明细上展示该保单的总理赔数,可以使用窗口函数实现,不需要提前聚合:
SELECT cclb.UnderWriting_Ref_UWRF, cclb.Cover_Class_CVCL, cclb.Annual_Premium_APRM, COUNT(csm.claim_ref_CMRF) OVER (PARTITION BY cclb.UnderWriting_Ref_UWRF) AS Claim_Count FROM Sandbox.DataTeam_Resources_Arc202512.AcctMon_Cover_Class_Live_Basic cclb LEFT JOIN Sandbox.DataTeam_AcctMonitoring_Arc202512.C_ClaimSummary_Merged csm ON csm.Underwriting_Ref_UWRF = cclb.UnderWriting_Ref_UWRF WHERE cclb.Cover_Class_CVCL = 'PMV' ORDER BY cclb.UnderWriting_Ref_UWRF ASC;
内容的提问来源于stack exchange,提问作者GaryBR
相关产品推荐
相关产品推荐

