![](/img/trans.png)
[英]Split a column into multiple columns by a delimiter (that may or may not be there)
[英]Split Column with delimiter into multiple columns
我有一张有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列的视图。 有人能帮我吗?
这是有关如何执行此操作的示例:
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,其中每个值都是e
元素,这是一些XML技巧。 然后使用value
函数中的索引检索单个元素。
由于这是一条语句,因此可以将其用作视图中的查询。
您可以使用返回位置的分割函数。 不幸的是,SQL Server 2016中的split_string()
尚不支持此功能。 ( Microsoft意识到这一点。 )
您可以找到用于此类功能的代码(例如, 此处 ,尽管我不建议使用该特定版本)。
然后,您可以执行以下操作:
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;
您可以按以下方式查询:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.