根据sql server 2008中的列值显示行

时间:2017-03-03 15:35:01

标签: sql-server sql-server-2008

我有列col1和col2

Col1             col2
abc,def          xyz,xyz
abc1,def1        xyz1,xyz1

我需要输出如下

Col1             col2
abc              xyz,xyz
def              xyz,xyz
abc1             xyz1,xyz1
def1             xyz1,xyz1

即如果col1包含2个值(abc,def)而col2包含2个值(xyz,xyz),那么我需要4行。同样col1和col2包含2个值,然后我需要9行。

请帮我在sql server

中获取输出

2 个答案:

答案 0 :(得分:2)

一点点XML和一个CROSS APPLY

选项1:没有拆分/解析功能

Declare @YourTable table (Col1 varchar(25),col2 varchar(25))
Insert Into @YourTable values
('abc,def','xyz,xyz'),
('abc1,def1','xyz1,xyz1')

Select col1 = B.RetVal
      ,col2 = A.col2
 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.Col1,',','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as X
                Cross Apply x.nodes('x') AS B(i)
             ) B

<强>返回

col1    col2
abc     xyz,xyz
def     xyz,xyz
abc1    xyz1,xyz1
def1    xyz1,xyz1

选项2:具有拆分/解析功能

Select col1 = B.RetVal
      ,col2 = A.col2
 From @YourTable A
 Cross Apply [dbo].[udf-Str-Parse](A.col1,',') B

感兴趣的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)

这是另一个例子:

;WITH A(Col1,col2)AS(
    SELECT 'abc,def','xyz,xyz' UNION all
    SELECT 'abc1,def1','xyz1,xyz1'
)
SELECT d.n,a.col2 FROM a
CROSS APPLY(VALUES(CONVERT(XML,'<n>'+REPLACE(col1,',','</n><n>')+'</n>'))) c(x)
CROSS APPLY(SELECT y.n.value('.','varchar(10)') FROM c.x.nodes('n') y(n)) d(n)
n          col2
---------- ---------
abc        xyz,xyz
def        xyz,xyz
abc1       xyz1,xyz1
def1       xyz1,xyz1