如何基于一个列值以逗号分隔创建行

时间:2017-04-06 12:33:58

标签: sql sql-server

Begin tran

create table #user_det 
             (user_id varchar(50), emp_id int, role varchar(500))

insert into #user_det (user_id , emp_id , role)
select 'Sankar', 431544 , '(Developer),(DBA),(Designer)'
union all
select 'Gowri', 145721 , '(DBA),(Designer)'
union all
select 'Raja', 101010 , 'ALL'

select * from #user_det

drop table #user_det

Rollback




OutPut Required:
===============

select 'Sankar' as user_id ,431544 as emp_id ,'Developer' as Role
union all
select 'Sankar' as user_id ,431544 as emp_id ,'DBA' as Role
union all
select 'Sankar' as user_id ,431544 as emp_id ,'Designer' as Role
union all
select 'Gowri' as user_id ,145721 as emp_id ,'DBA' as Role
union all
select 'Gowri' as user_id ,145721 as emp_id ,'Designer' as Role
union all
select 'Raja' as user_id ,101010 as emp_id ,'ALL' as Role

2 个答案:

答案 0 :(得分:1)

每个人都应该有一个好的分割/解析功能,因为SqlZim链接到。

如果您不想或不能使用UDF,这是另一种选择

Select A.user_id
      ,A.emp_id
      ,[role]    = Replace(Replace(B.RetVal,')',''),'(','')
 From #user_det 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.[Role],',','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as X
                Cross Apply x.nodes('x') AS B(i)
             ) B

<强>返回

enter image description here

答案 1 :(得分:0)

在SQL Server 2016+中,您可以使用string_split()

在2016年之前的SQL Server中,使用Jeff Moden的CSV Splitter表值函数:

select user_id, emp_id, Role = replace(replace(s.Item,'(',''),')','')
from #user_det u
  cross apply dbo.delimitedsplit8K(u.role,',') s

rextester演示:http://rextester.com/YVXGU42109

返回:

+---------+--------+-----------+
| user_id | emp_id |   Role    |
+---------+--------+-----------+
| Sankar  | 431544 | Developer |
| Sankar  | 431544 | DBA       |
| Sankar  | 431544 | Designer  |
| Gowri   | 145721 | DBA       |
| Gowri   | 145721 | Designer  |
| Raja    | 101010 | ALL       |
+---------+--------+-----------+

拆分字符串参考:

<小时/> Jeff Moden的delimitedsplit8K函数:

create function [dbo].[delimitedsplit8K] (
      @pstring varchar(8000)
    , @pdelimiter char(1)
  )
returns table with schemabinding as
 return
  with e1(N) as (
    select 1 union all select 1 union all select 1 union all 
    select 1 union all select 1 union all select 1 union all 
    select 1 union all select 1 union all select 1 union all select 1
  )
  , e2(N) as (select 1 from e1 a, e1 b)
  , e4(N) as (select 1 from e2 a, e2 b)
  , ctetally(N) as (
    select top (isnull(datalength(@pstring),0)) 
      row_number() over (order by (select null)) from e4
  )
  , ctestart(N1) as (
    select 1 union all
    select t.N+1 from ctetally t where substring(@pstring,t.N,1) = @pdelimiter
  )
  , ctelen(N1,L1) as (
    select s.N1,
      isnull(nullif(charindex(@pdelimiter,@pstring,s.N1),0)-s.N1,8000)
    from ctestart s
  )
 select itemnumber = row_number() over(order by l.N1)
      , item       = substring(@pstring, l.N1, l.L1)
   from ctelen l
;
go