SQL Server:筛选存在多个不同值的行
解决SQL Server中筛选存在多值组的行的问题
看起来你已经折腾了一天半找解决方案,别着急,我给你两个实用的SQL方案来搞定这个需求——从Table_D中筛选出那些**同一个Policynumber下存在不同BI_Limit或不同Premium**的所有记录。
方法1:使用窗口函数(推荐,性能友好)
窗口函数可以直观帮我们计算每个保单组内的不同值数量,再基于这个数量筛选目标行:
WITH PolicyVariations AS ( SELECT *, -- 统计当前保单号下BI_Limit的不同值总数 COUNT(DISTINCT BI_Limit) OVER (PARTITION BY Policynumber) AS BI_Limit_Distinct_Count, -- 统计当前保单号下Premium的不同值总数 COUNT(DISTINCT Premium) OVER (PARTITION BY Policynumber) AS Premium_Distinct_Count FROM Table_D ) SELECT Policynumber, EntryDate, BI_Limit, Premium FROM PolicyVariations -- 筛选出组内至少有一个字段存在多个不同值的行 WHERE BI_Limit_Distinct_Count > 1 OR Premium_Distinct_Count > 1;
逻辑说明:
- 先用CTE给每一行加上两个统计字段:分别是当前
Policynumber组内BI_Limit和Premium的不同值数量。 - 最后筛选出这两个统计值任意一个大于1的行,也就是组内存在不同值的所有记录。
方法2:使用EXISTS子查询
如果你更习惯子查询的写法,这个方案也能达到同样效果:
SELECT t1.* FROM Table_D t1 WHERE EXISTS ( SELECT 1 FROM Table_D t2 WHERE t2.Policynumber = t1.Policynumber -- 检查同组内是否存在BI_Limit或Premium不同的其他行 AND (t2.BI_Limit <> t1.BI_Limit OR t2.Premium <> t1.Premium) );
逻辑说明:
对于Table_D中的每一行,我们检查是否存在同一个Policynumber下的其他行,要么BI_Limit不同,要么Premium不同。如果存在,就保留当前行。
针对你的测试数据的结果
用这两个方法跑你的示例数据,会得到以下结果:
ABCD100001的两条记录(Premium不同)ABCD100003的三条记录(BI_Limit和Premium都有变化)
而ABCD100002这类只有单条记录的保单会被排除在外。
内容的提问来源于stack exchange,提问作者NP1996
相关产品推荐
相关产品推荐

