如何提取基于数据库列数据的逗号?

时间:2014-01-03 16:05:54

标签: sql sql-server tsql

如何从逗号分隔的列中提取数据?

这是我的数据库表,其中包含ID和数据两列。

ID      Data
-------------------
1       1, 2,3...50

我看起来像是否有任何逗号在数据列中识别,然后它将分隔该值并使列如下所示

ID     1    2    3
-------------------
1      1    2    3

如何使用T-SQL或普通查询来创建它?

2 个答案:

答案 0 :(得分:1)

测试数据

DECLARE @t TABLE (Data NVARCHAR(1000))

INSERT INTO @t
VALUES 
('1,2,3,4,5'),
('6,7,8,9,10'),
('A,B,C,D,E')

<强>查询

;WITH Split_Fields (Field, xmlfields)
AS
(
    SELECT Data AS Field,
    CONVERT(XML,'<Fields><field>'  
    + REPLACE(Data,',', '</field><field>') + '</field></Fields>') AS xmlfields
      FROM @t
)

 SELECT       
 xmlfields.value('/Fields[1]/field[1]','varchar(100)') AS Column1,    
 xmlfields.value('/Fields[1]/field[2]','varchar(100)') AS Column2,
 xmlfields.value('/Fields[1]/field[3]','varchar(100)') AS Column3,    
 xmlfields.value('/Fields[1]/field[4]','varchar(100)') AS Column4,
 xmlfields.value('/Fields[1]/field[5]','varchar(100)') AS Column5
 FROM Split_Fields

结果集

╔═════════╦═════════╦═════════╦═════════╦═════════╗
║ Column1 ║ Column2 ║ Column3 ║ Column4 ║ Column5 ║
╠═════════╬═════════╬═════════╬═════════╬═════════╣
║ 1       ║ 2       ║ 3       ║ 4       ║ 5       ║
║ 6       ║ 7       ║ 8       ║ 9       ║ 10      ║
║ A       ║ B       ║ C       ║ D       ║ E       ║
╚═════════╩═════════╩═════════╩═════════╩═════════╝

修改

在您要求我进一步解释如何将数据输入专栏后,我不知道我能解释多少。但是这里有一个关于您的数据的演示,我不知道如何将您的ID从-1更改为P00000000001,无论如何,这就是您如何使用您的数据。

<强>查询

DECLARE @t TABLE (DATA NVARCHAR(4000))
INSERT INTO @t
VALUES
('-1,H0000001,2011-02-19 00:00:00,I - D,GOA,INDIA ')

;WITH Split_Fields (Field, xmlfields)
AS
(
    SELECT Data AS Field,
    CONVERT(XML,'<Fields><field>'  
    + REPLACE(Data,',', '</field><field>') + '</field></Fields>') AS xmlfields
      FROM @t
)

 SELECT       
 xmlfields.value('/Fields[1]/field[1]','NVARCHAR(MAX)') AS Column1,    
 xmlfields.value('/Fields[1]/field[2]','NVARCHAR(MAX)') AS ID,
 xmlfields.value('/Fields[1]/field[3]','NVARCHAR(MAX)') AS [Date],    
 xmlfields.value('/Fields[1]/field[4]','NVARCHAR(MAX)') AS Div,
 xmlfields.value('/Fields[1]/field[5]','NVARCHAR(MAX)') AS [State],
 xmlfields.value('/Fields[1]/field[6]','NVARCHAR(MAX)') AS [Country]
 FROM Split_Fields

<强>结果

╔═════════╦══════════╦═════════════════════╦═══════╦═══════╦═════════╗
║ Column1 ║    ID    ║        Date         ║  Div  ║ State ║ Country ║
╠═════════╬══════════╬═════════════════════╬═══════╬═══════╬═════════╣
║      -1 ║ H0000001 ║ 2011-02-19 00:00:00 ║ I - D ║ GOA   ║ INDIA   ║
╚═════════╩══════════╩═════════════════════╩═══════╩═══════╩═════════╝

答案 1 :(得分:0)

我已经概述了使用UNPIVOT运算符的方法,该运算符将CSV解析为行,然后将行显示为位置列。它当然仅限于在unpivot轮廓中定义的位置列数。

要做到这一点没有限制,您将需要使用动态SQL来构建您的语句。查看this question以获取示例。

declare @a table (ID int, Data varchar(100));
insert into @a
    select 1, '1,2,3' union all
    select 2, '1,4' union all
    select 3, '1,5,X,,,,Y' union all
    select 4, '123';

declare @Numbers table (n int primary key); --use your own number table
insert into @Numbers
    select 1 union all select 2 union all select 3 union all
    select 4 union all select 5 union all select 6 union all
    select 7 union all select 8 union all select 9 union all 
    select 10;


select pvt.*
from    (
            select Id, d.Position, d.Value
            from @a
            cross
            apply   (   select  row_number()over(order by n),
                                substring(',' + Data + ',', n + 1, charindex(',', ',' + Data + ',', n + 1) - n -1)
                        from    @Numbers
                        where   n <= len(',' + Data + ',') - 1 and substring(',' + Data + ',', n, 1) = ','
                    )d(Position, Value)
        )s(Id, Position, Value)
pivot   (max(Value) for Position in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10]))pvt;