我有一张20列的桌子。其中一列包含由分号分隔的多个值。它看起来像这样:
-9;-9;-1;-9;-9;-9;-9;-9;-1;-9;-9;-9;-9;-9;-9;-9;-9;-9;-1;-9;-9;-9;-9;-9;-9;-9;-9;-9;-1;-9;-1;-9;-9;-9;-1;-9;-9;-9;-9;-9;-9;-1;-1;-1;-1;-9;-1;-1;-9;-9;-9;-9;-1;-9;-1;-9;-9;-9;-1;-9;-1;-9;-1;-9;-9;-9;-9;-1;-9;-9;-1;-1;-9;-1;-1;0000;FFF8;-9;-9;-9;-1;-9;-1;-9;FFF6;-9;-1;-9;-1;-9;-1;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9
它始终包含115个值。值可以是" -1"," -9"或十六进制数。
现在我想创建一个视图,其中包含原始的20列加上115列foreach分隔的字符串。有人能帮助我吗?
答案 0 :(得分:3)
这是一个如何执行此操作的示例:
DECLARE @tt TABLE(i INT IDENTITY,x VARCHAR(8000));
INSERT INTO @tt(x)VALUES('-9;-9;-1;-9;-9;-9;-9;-9;-1;-9;-9;-9;-9;-9;-9;-9;-9;-9;-1;-9;-9;-9;-9;-9;-9;-9;-9;-9;-1;-9;-1;-9;-9;-9;-1;-9;-9;-9;-9;-9;-9;-1;-1;-1;-1;-9;-1;-1;-9;-9;-9;-9;-1;-9;-1;-9;-9;-9;-1;-9;-1;-9;-1;-9;-9;-9;-9;-1;-9;-9;-1;-1;-9;-1;-1;0000;FFF8;-9;-9;-9;-1;-9;-1;-9;FFF6;-9;-1;-9;-1;-9;-1;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9;-9');
SELECT
i,
val1=n.v.value('/e[1]','VARCHAR(16)'),
val2=n.v.value('/e[2]','VARCHAR(16)'),
val3=n.v.value('/e[3]','VARCHAR(16)'),
-- ... repeat for val4 .. val114
val115=n.v.value('/e[115]','VARCHAR(16)')
FROM
@tt
CROSS APPLY (
SELECT
CAST('<e>'+REPLACE(x,';','</e><e>')+'</e>' AS XML) AS itm
) AS i
CROSS APPLY i.itm.nodes('/') AS n(v);
这是一些XML技巧,通过将带有分隔值的列设为XML,其中每个值都是e
元素。然后使用value
函数中的索引检索单个元素。
由于这是单个语句,因此可以在视图中用作查询。
答案 1 :(得分:2)
您可以使用返回位置的拆分功能。不幸的是,SQL Server 2016中的split_string()
尚不支持此功能。 (Microsoft is aware of this.)
您可以找到此类功能的代码(例如,here,但我不建议使用该特定版本。)
然后你可以这样做:
select t.*, v.*
from t cross apply
(select max(case when pos = 1 then val end) as col_001,
max(case when pos = 2 then val end) as col_002,
. . .
max(case when pos = 115 then val end) as col_115
from dbo.split(';', t.col) s(pos, val)
) v;
答案 2 :(得分:0)
您可以查询如下:
Declare @cols2 varchar(max)
Declare @query nvarchar(max)
--Row Numbers with tally
;with c1 as (
Select top(Select max(len(splitcolumn) - len(replace(splitcolumn,';',''))) from #data)
RowN = Row_number() over (order by (Select NULL))
from master..spt_values s1, master..spt_values
)
select @cols2 = stuff((select ','+QuoteName(RowN) from c1 group by RowN for xml path('')),1,1,'')
Select @query = '
Select * from (
Select Id, RowN, [Value] from #data
cross apply (
Select xm = CAST(''<x>'' + REPLACE((SELECT REPLACE(splitcolumn,'';'',''$$$SSText$$$'') AS [*] FOR XML PATH('''')),''$$$SSText$$$'',''</x><x>'')+ ''</x>'' AS XML)
) a
cross apply (
Select RowN = Row_Number() over (order by (SELECT NULL)), y.value(N''text()[1]'', N''nvarchar(MAX)'') as value
FROM a.xm.nodes(N''x'') as x(y)
) b
) rws
pivot (max([Value]) for RowN in (' + @cols2 + ')) p'
Exec sp_executesql @query