SQL Server分组取首行报错:REASON_CD重复问题排查
问题分析与解决
你碰到的Msg 8156错误,本质是CTE定义中出现了重复的REASON_CD列名。通常是因为关联的两张表都包含REASON_CD字段,而你在CTE的SELECT语句里要么重复选取了该字段(同时写了表1.REASON_CD和表2.REASON_CD),要么没有明确指定字段来源且未给别名,导致CTE生成的结果集中存在同名列。
正确CTE写法示例
写法1:先关联表并处理重复列
WITH cte AS ( SELECT t.ORDER_NO, t.REASON_CD, t.ROWID, ROW_NUMBER() OVER (PARTITION BY t.ORDER_NO ORDER BY t.ROWID DESC) AS rn FROM ( -- 关联时明确指定REASON_CD的来源,避免重复列 SELECT A.ORDER_NO, A.REASON_CD, -- 选择你实际需要的那张表的REASON_CD A.ROWID -- 若需合并ROWID,可改用MAX(A.ROWID)或按业务逻辑调整 FROM 表1 A JOIN 表2 B ON A.ORDER_NO = B.ORDER_NO -- 若要保留所有订单,可改用LEFT JOIN ) t ) SELECT ORDER_NO, REASON_CD FROM cte WHERE rn = 1;
写法2:直接在CTE中避免重复选列
WITH cte AS ( SELECT A.ORDER_NO, A.REASON_CD, -- 明确指定来自表A的REASON_CD A.ROWID, -- 按ORDER_NO分组,按ROWID倒序排序,取每组第一条 ROW_NUMBER() OVER (PARTITION BY A.ORDER_NO ORDER BY A.ROWID DESC) AS rn FROM 表1 A JOIN 表2 B ON A.ORDER_NO = B.ORDER_NO -- 如果需要用到表B的REASON_CD,需给它加别名,比如:B.REASON_CD AS B_REASON_CD ) SELECT ORDER_NO, REASON_CD FROM cte WHERE rn = 1;
为什么DISTINCT无法满足需求
DISTINCT是对查询结果的所有列组合进行去重,它无法实现“按ORDER_NO分组,取每组中ROWID最大的记录”的逻辑——即使你选中了ORDER_NO、REASON_CD、ROWID,DISTINCT只会保留唯一的列组合,而不会自动筛选每个ORDER_NO下的最新记录。
内容的提问来源于stack exchange,提问作者RodrigoPatrizi
相关产品推荐
相关产品推荐

