SQL查询去重并正确统计LDPARC及避免账户重复的问题求助
解决SQL统计地块编号重复及账户重复问题
看起来你的问题核心是两个点:一是统计每个账户对应的去重地块编号数量,二是避免结果中账户(ACCTNO)重复。原查询的问题主要出在窗口函数的分区逻辑错误,以及后续关联后的分组方式导致重复行。我来帮你一步步修正:
问题分析
- 原CTE中
COUNT(LDPARC) OVER (PARTITION BY LDPARC)是统计每个地块编号自身出现的次数,而非每个账户下的地块数量,分区字段应该是LDACCT(对应主表的ACCTNO)。 - 即使修正分区字段,窗口函数
COUNT(DISTINCT)确实不被支持,所以需要先对账户+地块编号去重,再统计数量。 - 原查询中
GROUP BY包含LDPARC,这会导致每个地块编号生成一行记录,自然出现ACCTNO重复;同时LEFT JOIN后加E.Liens >=1相当于把连接变成了INNER JOIN,丢失了没有法律描述的账户(如果需要保留的话可以调整)。
解决方案
我们可以分两步处理:先对法律描述表按账户+地块编号去重,再统计每个账户的地块数量,最后关联主表获取其他字段。如果同一个账户下的LDDSC1/LDDSC5等字段有多个值,你可以根据需求用聚合函数(比如STRING_AGG拼接、MAX取最大值等)处理:
修正后的查询语句
WITH Unique_Legal_Descriptions AS ( -- 第一步:获取每个账户下的唯一地块及关联字段(去重) SELECT DISTINCT LDACCT, LDDSC1, LDDSC5, LDTA, LDTYPT, LDPARC FROM tbl_Loan_Legal_Descriptions ), Account_Lien_Count AS ( -- 第二步:统计每个账户的去重地块数量 SELECT LDACCT, COUNT(LDPARC) AS Liens, -- 聚合其他字段(示例用STRING_AGG,根据实际需求调整) STRING_AGG(DISTINCT LDDSC1, ', ') AS LDDSC1_List, STRING_AGG(DISTINCT LDDSC5, ', ') AS LDDSC5_List, MAX(LDTA) AS LDTA, -- 如果LDTA每个账户唯一,用MAX/Min都可以 MAX(LDTYPT) AS LDTYPT FROM Unique_Legal_Descriptions GROUP BY LDACCT ) -- 第三步:关联主表,获取最终结果(每个账户一行) SELECT A.ACCTNO, ALC.LDDSC1_List, ALC.LDDSC5_List, ALC.LDTA, ALC.LDTYPT, ALC.Liens, A.CALREP, A.SNAME FROM tbl_loan_master A LEFT JOIN Account_Lien_Count ALC ON A.ACCTNO = ALC.LDACCT WHERE -- 如果需要保留没有法律描述的账户,去掉ALC.Liens >=1;否则保留 (ALC.Liens >= 1 OR ALC.Liens IS NULL) AND A.STATUS <> 2 AND A.QRYBAL > 0 ORDER BY A.ACCTNO;
关键说明
- 去重处理:
Unique_Legal_DescriptionsCTE先对LDACCT + LDPARC去重,确保每个账户的每个地块只统计一次。 - 聚合字段:如果
LDDSC1/LDDSC5等字段在同一个账户下有多个不同值,用STRING_AGG可以把所有值拼接成字符串;如果这些字段和账户是一一对应的,直接用MAX/MIN即可。 - 连接逻辑:保留
LEFT JOIN并调整WHERE条件,可以选择是否保留没有法律描述的账户;如果只需要有地块的账户,把条件改成ALC.Liens >=1即可。
如果你的业务中LDDSC1/LDDSC5等字段和LDPARC是一一对应的(即每个地块对应唯一的这些字段),也可以简化写法,直接在统计数量时关联:
WITH Account_Lien_Count AS ( SELECT LDACCT, COUNT(DISTINCT LDPARC) AS Liens, LDDSC1, LDDSC5, LDTA, LDTYPT FROM tbl_Loan_Legal_Descriptions GROUP BY LDACCT, LDDSC1, LDDSC5, LDTA, LDTYPT ) SELECT A.ACCTNO, ALC.LDDSC1, ALC.LDDSC5, ALC.LDTA, ALC.LDTYPT, ALC.Liens, A.CALREP, A.SNAME FROM tbl_loan_master A LEFT JOIN Account_Lien_Count ALC ON A.ACCTNO = ALC.LDACCT WHERE (ALC.Liens >= 1 OR ALC.Liens IS NULL) AND A.STATUS <> 2 AND A.QRYBAL > 0 ORDER BY A.ACCTNO;
这个写法适用于每个账户的LDDSC1/LDDSC5等字段组合唯一的场景,这样分组后每个账户仍然只有一行记录。
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

