繁体   English   中英

使用分隔符将列拆分为多列

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM