基于Row_number筛选#T/#T1关联#Maintable的SQL查询问题
修正后的SQL解决方案
核心思路是先统计#T表中每个id的记录数,再根据数量判断取#T还是#T1的reason,最后关联#Maintable确保只返回主表的5条记录。
方法一:分步CTE+条件关联
WITH T_Count AS ( -- 统计#T中每个id的reason记录数 SELECT id, COUNT(*) AS reason_count FROM #T GROUP BY id ) SELECT mt.*, -- 根据记录数选择对应reason CASE WHEN tc.reason_count > 1 THEN t1.reason ELSE t.reason END AS final_reason FROM #Maintable mt -- 关联统计结果 LEFT JOIN T_Count tc ON mt.id = tc.id -- 仅当#T中该id只有1条记录时,关联#T取reason LEFT JOIN #T t ON mt.id = t.id AND tc.reason_count = 1 -- 仅当#T中该id记录数>1时,关联#T1取reason LEFT JOIN #T1 t1 ON mt.id = t1.id AND tc.reason_count > 1 -- 只保留主表存在的记录 WHERE mt.id IS NOT NULL -- 确保每个id仅返回一条记录(需替换"其他字段"为#Maintable的所有字段) GROUP BY mt.id, mt.其他字段, tc.reason_count, COALESCE(t.reason, t1.reason)
方法二:子查询直接获取对应reason(更简洁)
如果#T和#T1中每个id都只有一条reason记录,用这个写法更高效:
WITH T_Count AS ( SELECT id, COUNT(*) AS reason_count FROM #T GROUP BY id ) SELECT mt.*, COALESCE( CASE WHEN tc.reason_count > 1 THEN t1.reason END, t.reason ) AS final_reason FROM #Maintable mt LEFT JOIN T_Count tc ON mt.id = tc.id LEFT JOIN #T t ON mt.id = t.id LEFT JOIN #T1 t1 ON mt.id = t1.id WHERE mt.id IS NOT NULL -- 去重确保每条主表记录唯一 GROUP BY mt.id, mt.其他字段, tc.reason_count, t.reason, t1.reason
问题排查:原Row_Number写法为何返回多余记录?
大概率是分区逻辑错误(比如没按id分区),或者关联时未添加过滤条件,导致同一个id匹配了多条reason记录。上面的写法通过先统计记录数,再针对性关联,从根源避免了重复匹配。
内容的提问来源于stack exchange,提问作者SQL2023
相关产品推荐
相关产品推荐

