拆分逗号分隔的Id值并从另一个表

时间:2015-06-15 12:56:55

标签: sql sql-server

我有以下两个表

Id      Members
+++     +++++++
1       8,9,15,13
2       1,2,5,9,11

用户

Id      Username
+++     ++++++++
1       Admin
2       Test 
3       another user

我需要结果如下:

最终结果

Id        Team
++++++    ++++++
1         Admin,test user, new user
2         sweet user, nice user, keep looking user

我使用以下查询,但问题是它是子查询,并且它不返回一行:

SELECT [Id]
      ,[Username] as Manager
,[Teams].[Name]
      ,[Teams].[Description]
      ,(

       select ', '+T1.Username
       from [Users] as T1
       where ','+T2.Memebers+',' like '%,'+cast(T1.UserID as varchar(10))+',%'
       for xml path(''), type
       ).value('substring(text()[1], 3)', 'varchar(max)') as Memebers
from [Metarabia_Teams] as T2
      ) as Memebers
  FROM [dbo].[Teams],[dbo].[Users]
  where [Teams].[ManagerId] = [DNNTest].[dbo].[Users].UserID

2 个答案:

答案 0 :(得分:0)

It is possible to replace the ids with the names by first splitting the data into rows and then putting it back together. This is of course a really bad way of doing things, you should rather have the data stored so that one column contains one id / name, and not multiple things.

select t.id, isnull(u.username,'Missing: ' + l.item) as Name
into #tmp
from team t
cross apply dbo.DelimitedSplit8K(members, ',') l
left outer join users u on u.id = l.item

SELECT id, STUFF((SELECT ', ' + Name 
  FROM #tmp AS t2
   WHERE t2.id = t.id 
   FOR XML PATH('')), 1, 2, '') as Names
FROM #tmp AS t
GROUP BY id

This requires that you have a string splitting function, for example DelimitedSplit8K by Jeff Moden.

You can test this in SQL Fiddle.

If the user is missing, the SQL adds 'Missing' + the user id instead of the name.

答案 1 :(得分:0)

我们可以通过使用Cross Apply和XML Path()实现这一点。基于您提供的结果集

的假设数据
declare @t table (Id int,Members varchar(20))
insert into @t (Id,Members)values (1,'8,9,15,13'),(2,'1,2,5,9,11')

declare @tt table (Id int,username varchar(20))
insert into @tt(Id,username)values 
(1,'Admin'),
(2,'Test'),
(3,'Anotheruser'),
(5,'niceuser'),
(4,'nice'),
(5,'niceuser'),
(6,'helper')
,(7,'quite'),
(8,'just'),
(9,'not'),
(11,'keeplookinguser'),
(13,'lookinguser'),
(15,'keepRocking')

;WITH CTE AS (
SELECT   Id,
     Split.a.value('.', 'VARCHAR(100)') AS String  
 FROM  (SELECT ID,  
         CAST ('<M>' + REPLACE([Members], ',', '</M><M>') + '</M>' AS XML) AS String  
     FROM  @t) AS A CROSS APPLY String.nodes ('/M') AS Split(a))

  ,CTE2 as (          
SELECT t.Id, STUFF((SELECT ', ' + T2.username 
  FROM @tt AS t2
   WHERE t2.id = t.String 
   FOR XML PATH('')), 1, 2, '') as Names
FROM CTE AS t
GROUP BY id,string )
SELECT DISTINCT t.Id, STUFF((SELECT ', ' + T2.Names 
  FROM CTE2 AS t2
   WHERE t2.id = t.id 
   GROUP BY id,Names 
   ORDER BY names DEsc
   FOR XML PATH('')), 1, 2, '') as Names
FROM CTE2 AS t