我具有以下数据,我试图取消这些数据。我正在处理的列数一直到F600
基本上,SEQ_NUM行数据成为名为SEQ_NUM的列,而Cells仍为列,但没有SEQ_NUM行,新列“ NewCol”将具有内容数据,而SEQ_NUM行数据现在是一列。
我想获得这种格式。现在,我可以使用UNION ALL并通过游标遍历从F2到F600的所有列,并与SEQ_NUM的数据交叉联接,但是我认为有更好的解决方案。
可以使用的数据版本如下:
create table #t (cells varchar(15), f2 int, f3 int, f4 int);
insert #t values
('seq_num', 1, 2, 3),
('linkA', 4290, 42521, 42551),
('linkB', 0, 0, 0),
('linkC', 1332, 0, 15);
正如avery_larry所提到的,这似乎是基本原理。我认为您可能会被甩掉的是'seq_num'与列名是多余的。列“ f2”至“ f600”已经按顺序排列。因此,只需取消透视,即可从透视列标签中提取整数,然后减去一个。在执行所有这些操作时,请忽略“ seq_num”行。
select up.cells,
seq_num = try_convert(int,replace(up.col, 'f', '')) - 1,
up.val
from #t
unpivot (val for col in (f2, f3, f4)) up -- you write out to 'f600'
where cells <> 'seq_num';
[如果您希望避免将'f2'写到'f600',则可以动态进行。首先构建包含所有列名称的字符串,然后将其插入“ in”语句中。
declare
@cols varchar(max) = '',
@f int = 1,
@maxF int = 4; -- you change to 600
while @f < @maxF begin
set @f += 1;
set @cols += 'f' + convert(varchar(3), @f) + iif(@f <> @maxF, ',', '');
end
declare @sql nvarchar(max) = '
select up.cells,
seq_num = try_convert(int,replace(up.col, ''f'', '''')) - 1,
up.val
from #t
unpivot (val for col in (' + @cols + ')) up
where cells <> ''seq_num''
';
exec (@sql);