SQL Server中WITH子句JOIN后SELECT *遇重复列报错,求解决方案
解决SQL Server中CTE关联表用
*导致重复列报错的问题 我之前处理过几乎一模一样的场景——两个大表(几百列)关联,想用WITH子句保持代码可读性,用*避免手动列所有列,但SQL Server不支持USING(),一执行就报重复列的错,着实头疼。给你两个实用的解决思路:
方案1:用动态SQL自动生成无重复的列列表
这是最适合大表的方案,完全不用手动写几百列,还能自动适配表结构变更。核心是利用SQL Server的系统视图sys.columns来获取两个表的列名,排除重复的id后拼接成合法的查询语句:
DECLARE @cols NVARCHAR(MAX); -- 拼接t1的所有列 + t2中除id外的所有列 SELECT @cols = STRING_AGG(QUOTENAME(c.name), ', ') FROM ( -- 先取t1的全部列 SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('t1') UNION ALL -- 再取t2中排除id的列 SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('t2') AND name <> 'id' ) c; -- 构造带CTE的完整SQL并执行 DECLARE @sql NVARCHAR(MAX) = N' WITH t12 AS ( SELECT ' + @cols + N' FROM t1 INNER JOIN t2 ON t1.id = t2.id ) SELECT * FROM t12'; EXEC sp_executesql @sql;
这个方法既保留了WITH子句的可读性,又不用手动维护繁琐的列列表,后续表加列减列都不用改这段代码,非常省心。
方案2:显式指定重复列(仅适合列数较少场景)
如果实在不想用动态SQL,只能退一步显式处理重复列,但这个方法需要手动排除t2的id列,对你200+列的场景不太友好,仅作参考:
WITH t12 AS ( SELECT t1.id, -- 只保留一个id列(选t1或t2的均可) t1.*, -- 这里需要手动列出t2中除id外的所有列,列数多的话不推荐 t2.col1, t2.col2, ..., t2.colN FROM t1 INNER JOIN t2 ON t1.id = t2.id ) SELECT * FROM t12;
内容的提问来源于stack exchange,提问作者Davor Josipovic
相关产品推荐
相关产品推荐

