在SQL Server中用CASE结合PARTITION BY实现特定日期匹配筛选
修正SQL以满足匹配记录筛选需求
我来帮你搞定这个SQL逻辑的问题,先明确你的核心需求:当同一分组下存在多条记录时,只保留LearningStartDate等于LearnDelFAMDateFrom的那条记录的对应值;如果没有符合条件的记录,就返回空值。
先看你原来的CASE语句,里面有个明显的逻辑错误:(rn =1 and rn > 1)是矛盾的,永远不会触发,而且窗口函数的部分也没写完,这会导致整个逻辑失效。下面给你两种适配不同场景的修正方案:
方案1:优先保留相等匹配的记录(通用场景)
这个方案的逻辑是:不管分组内有多少条记录,我们都优先取LearningStartDate = LearnDelFAMDateFrom的那条;如果没有这样的记录,就返回空。
SELECT ukprn, aimseqnumber, LearnRefNumber, LearnDelFAMCode, LearnDelFAMType, LearnDelFAMDateFrom, LearningStartDate, CASE WHEN rn = 1 THEN LearnDelFAMDateFrom ELSE '' END AS LearnDelFAMDateFromMOD FROM ( SELECT *, -- 按业务主键分组,把符合相等条件的记录标记为最高优先级(rn=1) ROW_NUMBER() OVER ( PARTITION BY ukprn, aimseqnumber, LearnRefNumber ORDER BY CASE WHEN LearningStartDate = LearnDelFAMDateFrom THEN 0 ELSE 1 END ) AS rn FROM your_table_name -- 替换成你的实际表名 ) AS subquery
逻辑说明:
- 子查询里用
ROW_NUMBER()窗口函数,按你的业务主键(比如ukprn、aimseqnumber、LearnRefNumber)分组排序:满足相等条件的记录会被排在最前面,标记为rn=1,其他记录依次编号。 - 外层CASE只取
rn=1的记录值,其他情况返回空,完美适配需求。
方案2:区分单条/多条记录场景
如果你的需求是更细分的:
- 当分组内只有1条记录:直接返回
LearnDelFAMDateFrom的值 - 当分组内有多条记录:只返回其中符合
LearningStartDate = LearnDelFAMDateFrom的那条的值,没有符合的就返回空
那可以用下面的代码:
SELECT ukprn, aimseqnumber, LearnRefNumber, LearnDelFAMCode, LearnDelFAMType, LearnDelFAMDateFrom, LearningStartDate, CASE -- 单条记录直接返回值 WHEN total_records = 1 THEN LearnDelFAMDateFrom -- 多条记录时,只取符合相等条件的优先级最高的那条 WHEN total_records > 1 AND rn = 1 THEN LearnDelFAMDateFrom ELSE '' END AS LearnDelFAMDateFromMOD FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY ukprn, aimseqnumber, LearnRefNumber ORDER BY CASE WHEN LearningStartDate = LearnDelFAMDateFrom THEN 0 ELSE 1 END ) AS rn, -- 统计每个分组的总记录数 COUNT(*) OVER (PARTITION BY ukprn, aimseqnumber, LearnRefNumber) AS total_records FROM your_table_name ) AS subquery
逻辑说明:
- 新增了
total_records字段来统计每个分组的记录数量,以此区分单条/多条场景。 - 多条场景下依然优先标记符合相等条件的记录,确保只取正确的那条值。
内容的提问来源于stack exchange,提问作者Ashikur Rahman
相关产品推荐
相关产品推荐

