从行中断多个值

时间:2017-04-10 19:00:43

标签: sql sql-server-2008

我有一个选择,给我一个结果,如:

A, B, C
C, D, E
G, A
NULL
O, U, B, X

我希望得到如下结果:

A
B
C
D
E
G
O
U
X

因此,代替行中的多个值,每个值应与DISTINCT在一行并且没有NULL

尝试使用SQLFIDDLE创建示例,但它无法正常工作。

2 个答案:

答案 0 :(得分:1)

每个人都应该有一个好的分裂/解析功能。

没有UDF的选项1

Declare @YourTable table (SomeCol varchar(100))
Insert Into @YourTable values
('A, B, C'),
('C, D, E'),
('G, A'),
(NULL),
('O, U, B, X')

Select Distinct B.RetVal
 From  @YourTable A
 Cross Apply (
                Select RetSeq = Row_Number() over (Order By (Select null))
                      ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
                From  (Select x = Cast('<x>' + replace((Select replace(A.SomeCol,',','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as X
                Cross Apply x.nodes('x') AS B(i)
             ) B
 Where B.RetVal is not null

选项2使用Parse / Spit UDF

Select Distinct B.RetVal
 From  @YourTable A
 Cross Apply [dbo].[udf-Str-Parse](A.SomeCol,',') B
 Where B.RetVal is not null

返回

RetVal
A
B
C
D
E
G
O
U
X

感兴趣的UDF

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    Select RetSeq = Row_Number() over (Order By (Select null))
          ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From  (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as X
    Cross Apply x.nodes('x') AS B(i)
);
--Thanks Shnugo for making this XML safe
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
--Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',')

答案 1 :(得分:0)

您可以使用cross apply取消隐藏它们。其余的只是select distinct

select distinct v.val
from t cross apply
     (values (col1), (col2), (col3)) val
where val is not null;