2011-06-17 45 views
4

在SQL Server 2008数据库中,我有一列包含多个由分号分隔的值。一些值包含冒号。样本数据: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功能,但他们似乎都对付硬编码的字符串,而不是来自表中列的字符串。我怎样才能做到这一点?

编辑: Thomas'answer got it!这是我最后的查询:

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

+0

你可以使用C#,或者你有使用TSQL? –

+0

我希望完全使用SQL Server Management Studio中的T-SQL来完成此操作。 –

回答

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) 
+0

如果您使用这种技术,您需要注意数据中的“<”和“&”。 –

+0

@迈克尔埃里克森 - 这可以克服。发布了允许使用Xml保留符号的版本。 – Thomas

+0

@Mikael Eriksson - (很显然,如果源数据中可能包含“{”或“}”,则应使用不同的标记。) – Thomas

3

你们用交叉分割功能应用:

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

这里SplitString有两个参数,字符串柱和分离,并有一个名为part其中返回值列。