SQL Server 2017多查询关联时如何排除指定列查询所有列?
在SQL Server 2017里,可惜并没有直接支持SELECT * EXCEPT [列名]这种语法,但咱们有几个实用的办法能搞定你这个需求,下面分场景给你唠唠:
方法1:利用系统视图动态生成列列表(推荐批量/自动化场景)
这种方法适合需要重复执行或者列特别多的情况,核心思路是通过系统视图拿到目标列的列表,再拼接成完整的SQL语句。
举个例子,你要处理t1子查询,需要排除id1和col_a列,可以先把t1的结果存入临时表(固定住子查询的结构,方便后续获取列名):
-- 先把query1的结果存入临时表 SELECT * INTO #temp_t1 FROM (query1) AS t1; -- 生成t1需要的列列表(排除指定列) SELECT STRING_AGG(QUOTENAME(name), ', ') AS select_columns FROM tempdb.sys.columns WHERE object_id = OBJECT_ID('tempdb..#temp_t1') AND name NOT IN ('id1', 'col_a'); -- 这里填你要排除的列名
执行上面的语句后,你会得到一串用逗号分隔的列名(比如[col_b], [col_c], [col_d]),直接把这串内容替换到主查询里t1.*的位置就行。
如果想一次性生成整个主查询并执行,可以用动态SQL拼接:
DECLARE @t1_cols NVARCHAR(MAX), @t2_cols NVARCHAR(MAX), @full_sql NVARCHAR(MAX); -- 先把两个子查询的结果存入临时表 SELECT * INTO #temp_t1 FROM (query1) AS t1; SELECT * INTO #temp_t2 FROM (query2) AS t2; -- 获取t1需要的列(排除id1, col_a) SELECT @t1_cols = STRING_AGG(QUOTENAME(name), ', ') FROM tempdb.sys.columns WHERE object_id = OBJECT_ID('tempdb..#temp_t1') AND name NOT IN ('id1', 'col_a'); -- 获取t2需要的列(排除id2, col_x) SELECT @t2_cols = STRING_AGG(QUOTENAME(name), ', ') FROM tempdb.sys.columns WHERE object_id = OBJECT_ID('tempdb..#temp_t2') AND name NOT IN ('id2', 'col_x'); -- 拼接完整的查询语句 SET @full_sql = N'SELECT ' + @t1_cols + N', ' + @t2_cols + N', t3.* FROM (query1) AS t1, (query2) AS t2, (query3) AS t3 WHERE t1.id1 = t2.id2 AND t1.id1 = t3.id3'; -- 执行动态SQL EXEC sp_executesql @full_sql;
方法2:手动选择列(适合临时查询)
如果只是偶尔查一次,用SSMS的GUI操作更省事:
- 先单独执行子查询(比如
query1),在结果窗口选择「结果到网格」; - 右键结果集的表头,选择「复制列名」;
- 把复制的列名粘贴到主查询里
t1.*的位置,手动删掉不需要的列就行。
这种方法虽然手动,但不用写复杂的动态SQL,临时用起来特别快。
方法3:直接列出需要的列(适合排除列很少的情况)
要是每个子查询要排除的列没几个,直接手动列出所有需要的列最直观:
SELECT t1.col_b, t1.col_c, t1.col_d, -- 列出t1所有需要的列,排除id1和col_a t2.col_y, t2.col_z, -- 列出t2需要的列,排除id2和col_x t3.* FROM (query1) AS t1, (query2) AS t2, (query3) AS t3 WHERE t1.id1 = t2.id2 AND t1.id1 = t3.id3;
这种方法的好处是一目了然,缺点是如果子查询的列有变动,得手动更新列列表。
注意事项
- 动态SQL要注意注入风险,如果你的排除列是固定值或者来自可信来源,就不用担心;
- 临时表的方式要确保子查询的结构稳定,否则生成的列列表可能出错;
- 如果是SQL Server 2016及更早版本,
STRING_AGG函数不支持,需要用FOR XML PATH来拼接列名。
内容的提问来源于stack exchange,提问作者Elmojioo
相关产品推荐
相关产品推荐

