删除未使用的(生成的)列

Remove unused (generated) columns

我正在尝试拆分名称值以便之后对其进行分析。为此,我在 T-SQL 中生成 15 列,然后使用 UDF (https://social.technet.microsoft.com/wiki/contents/articles/26937.t-sql-splitting-a-string-into-multiple-columns.aspx) 将列 'value' 拆分为新列(使用 space 作为分隔符).到目前为止,我按照预期得到了以下结果,非常好...

id|value  |col_1|col_2|col_3|col_4|col_5|col_6|col_7|col_8|col_9|col_10|col_11|col_12|col_13|col_14|col_15
1 |xxx    |x    |x    |x    |     |     |     |     |     |     |      |      |      |      |      |     
2 |x      |x    |     |     |     |     |     |     |     |     |      |      |      |      |      |
3 |xxxxxxx|x    |x    |x    |x    |x    |x    |x    |     |     |      |      |      |      |      |
4 |xxxx   |x    |x    |x    |x    |     |     |     |     |     |      |      |      |      |      |

对我的解决方案感到满意,我开始编写代码以真正分析各个部分。然而,我的同事想出了一个小废话,他说不使用的列应该被删除。因为我受命帮助同事而不是告诉他们他们的问题有多么愚蠢,所以我说我会调查一下。

问题是我的自我不允许我为此使用 15 行硬编码。我真的很想用游标来做这件事,这样如果以后我需要解析更长的字符串(顺便说一句,这实际上是可以假设的),代码就会继续工作。我在游标中使用数字来创建列名。然后我认为使用 'select 1 from #1 where len(column_name)' 查询来查看该列是否正在使用是个好主意。但是现在我无法创建包含创建的 column_name 的动态 sql。这是一个问题,因为我需要相同的 column_name 才能在发现它为空时将其实际删除。

while @count < @max_nr_columns
begin
set @colname = 'part' + convert(varchar(255), (@count + 1))
declare @max_col_real nvarchar(4000)-- = N'max_col_real_is_empty'
declare @mc int = 0
exec('sp_executesql (select 1 from #1 where ' + @colname + ' is not null), N''@max_col_real nvarchar(4000) output'', @max_col_real output')
set @max_col_real = (@sql)
set @count = @count + 1
end
print @max_col_real

它抛出有关逗号的错误,这意味着问题出在执行行中。谁能指出我删除第 8-15 列的正确方向?或者告诉我我在上面的代码中做错了什么?

我正在使用 SQL2014,但希望在 2008 之前保持向下兼容。

您可以旋转以抑制空值。 Pivot、Stuff 和 FOR XML 应该从 2008 年开始可用。

所以例子可以是

SQL 使用 DYNAMIC UNPIVOT 更新代码

   Create table #temp (id int, value nvarchar(50),col_1 nvarchar(50),col_2 nvarchar(50),col_3 nvarchar(50),col_4 nvarchar(50),col_5 nvarchar(50),col_6 nvarchar(50),col_7 nvarchar(50),col_8 nvarchar(50),col_9 nvarchar(50))

insert into #temp
values


(1 ,'xxx'    ,'x','x','x',null,null,null,null,null,null),    
(2 ,'x'      ,'x',null,null,null,null,null,null,null,null), 
(3 ,'xxxxxxx','x','x','x','x','x','x','x',null,null),  
(4 ,'xxxx'   ,'x','x','x','x',null,null,null,null,null) 




declare @gruppe nvarchar(max)
      declare @gruppeSql nvarchar(max)
      declare @SQL nvarchar(max)
      DECLARE myCustomers CURSOR FOR

Select [Name] from tempdb.sys.columns where object_id = object_id('tempdb..#temp') 
and [name] like 'col%' 

      set @gruppeSql = ''
      OPEN myCustomers
       FETCH NEXT FROM myCustomers INTO @gruppe
      IF (@@FETCH_STATUS>=0)
      BEGIN
      SET @gruppeSql = @gruppeSql +'[' +@gruppe+']'
      FETCH NEXT FROM myCustomers INTO @gruppe
       END
       WHILE (@@FETCH_STATUS<>-1)
       BEGIN
       IF (@@FETCH_STATUS<>-2)

       SET @gruppeSql = @gruppeSql  + ',[' +@gruppe+']'
       FETCH NEXT FROM myCustomers INTO @gruppe
       END
       CLOSE myCustomers
       DEALLOCATE myCustomers 

      SET @gruppeSql = replace(@gruppesql,'''','')
      print @gruppeSql
      --select @gruppeSql
       SET @SQL = '


        SELECT distinct Pets = ''Select'' + STUFF((SELECT N'', '' + cols 
  FROM (select distinct cols from #temp a

UNPIVOT (Rowno for Cols in('+@gruppeSql+')) as pvy ) AS p2

   FOR XML PATH(N'''')), 1, 2, N'' '')'




      print @sql
      exec(@sql)
      drop table #temp