SQL to Make XML Path列表

时间:2016-09-12 13:05:55

标签: sql sql-server xml

我有以下SQL Server查询,它将逗号分隔的列表分成一个字段。

结果如下2003, 9083, 4567, 3214

问题:将它放入列中的最佳方法(SQL语法)是什么?

意思是,我需要将这些列显示为“2003”的1列,“9083”1列的1列,“4567”..等。 显然,根据我给出的策略ID,列数是动态的。任何想法都会受到最高的赞赏。

我的查询如下。

SELECT DISTINCT x.ClassCode + ', '
FROM PremByClass x
WHERE x.PolicyId = 1673885
FOR XML PATH('')

3 个答案:

答案 0 :(得分:1)

如果您取出XML和逗号,则留下

SELECT DISTINCT x.ClassCode
FROM PremByClass x
WHERE x.PolicyId = 1673885

它为您提供了一列值,将其转换为需要PIVOT它的列。但是,您需要指定列的名称。

此答案中有更多信息https://stackoverflow.com/a/15931734/350188

答案 1 :(得分:1)

您需要PIVOT,如果值的数量可能不同 - 动态SQL:

SELECT *
FROM (
SELECT DISTINCT ClassCode,
                ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM PremByClass 
WHERE PolicyId = 1673885
) as t
PIVOT (
    MAX(ClassCode) FOR RN IN ([1],[2],[3],[4])
) as pvt

会给你:

1       2       3       4
-----------------------------
2003    9083    4567    3214

动态SQL将类似于:

DECLARE @sql nvarchar(max),
        @columns nvarchar(max)

SELECT @columns = STUFF((
    SELECT DISTINCT ','+QUOTENAME(ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) 
    FROM PremByClass 
    WHERE PolicyId = 1673885
    FOR XML PATH('')
),1,1,'')

SELECT @sql = N'
SELECT *
FROM (
SELECT DISTINCT ClassCode,
                ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM PremByClass 
WHERE PolicyId = 1673885
) as t
PIVOT (
    MAX(ClassCode) FOR RN IN ('+@columns+')
) as pvt'

EXEC sp_executesql @sql

答案 2 :(得分:1)

假设csv字符串中的数字数量有限制。
您可以将其转换或转换为xml类型,然后将值放在您期望的任意数量的列中。

在此示例中,假设文本中的值不超过6个:

declare @PolicyId INT = 1673885;

select PolicyId
,x.value('/x[1]','int') as n1
,x.value('/x[2]','int') as n2
,x.value('/x[3]','int') as n3
,x.value('/x[4]','int') as n4
,x.value('/x[5]','int') as n5
,x.value('/x[6]','int') as n6
from (
  select 
  PolicyId, 
  cast('<x>'+replace(ClassCode,',','</x><x>')+'</x>' as xml) as x 
  from PremByClass
  where PolicyId = @PolicyId
) q;