SQL Server 2008 - 将多值列拆分为具有唯一值的行

时间:2011-06-17 22:12:42

标签: tsql sql-server-2008 split pivot

在SQL Server 2008数据库中,我有一个列,其中多个值由分号分隔。某些值包含冒号。样本数据:

key:value;key2:value;blah;foo;bar;A sample value:whee;others
key:value;blah;bar;others
A sample value:whee

我想从不同行中的每一行获取所有唯一值:

key:value
key2:value
blah
foo
bar
A sample value:whee
others

我查看了各种split函数,但它们似乎都处理硬编码字符串,而不是来自表中列的字符串。我怎么能这样做?

编辑:托马斯回答得到了!这是我的最后一个问题:

With SampleInputs As
    (
    select distinct myColumn from [myDatabase].[dbo].myTable where myColumn != ''
    )
    , XmlCte As
    (
    Select Cast( '<z>' + Replace( myColumn, ';', '</z><z>' ) + '</z>' As xml ) As XmlValue
    From SampleInputs As I
    )
Select Distinct Y.z.value('.','nvarchar(max)') As Value
From XmlCte
    Cross Apply XmlValue.nodes('//z') Y(z)

我猜测XmlValue.nodesY.z.value的东西是神奇的。 O_O

2 个答案:

答案 0 :(得分:3)

使用分割功能,您可以使用交叉申请:

select distinct SS.part
from YourTable
  cross apply dbo.SplitString(YourColumn, ';') as SS

这里,SplitString接受两个参数,即字符串列和分隔符,并有一个名为part的列,其中返回值。

答案 1 :(得分:2)

With SampleInputs As
    (
    Select 'key:value;key2:value;blah;foo;bar;A sample value:whee;others' As [Data]
    Union All Select 'key:value;blah;bar;others' 
    Union All Select 'A sample value:whee'
    )
    , XmlCte As
    (
    Select Cast( '<z>' + Replace( I.[Data], ';', '</z><z>' ) + '</z>' As xml ) As XmlValue
    From SampleInputs As I
    )
Select Distinct Y.z.value('.','nvarchar(max)') As Value
From XmlCte
    Cross Apply XmlValue.nodes('//z') Y(z)

<强>更新

以上是处理实体的上述版本:

With SampleInputs As
    (
    Select 'key:value;key2:value;blah;foo;bar;A sample value:whee;others' As [Data]
    Union All Select 'key:value;blah;bar;others' 
    Union All Select 'A sample value:whee'
    Union All Select 'A sample value:<Oops>'
    )
    , XmlGoo As
    (
    Select Cast(
            Replace(
                Replace( Cast( Z.XmlValue As nvarchar(max) ), '{{', '<z>' )
                , '}}', '</z>')
            As Xml ) As Xmlvalue
    From    (
            Select Cast(
                    (
                    Select '{{' + Replace( [Data], ';', '}}{{' ) + '}}'
                    From SampleInputs
                    For Xml Path(''), type
                    ) As Xml ) As XmlValue
            ) As Z
    )
Select Distinct Z.data.value('.', 'nvarchar(max)')
From XmlGoo
    Cross Apply XmlValue.nodes('/z') Z(data)