如何将STUFF()应用于逗号分隔

时间:2013-01-18 19:31:21

标签: sql-server tsql

我读到了这个:http://blog.sqlauthority.com/2012/09/14/sql-server-grouping-by-multiple-columns-to-single-column-as-a-string/

我可以将其应用于我的一个查询:

SELECT t.TicketID, STUFF(
(SELECT ',' + tt.Tag
FROM TicketTag tt
WHERE tt.TicketID = t.TicketID
FOR XML PATH('')),1,1,'') AS CSV
FROM Ticket AS t
GROUP BY t.TicketID
GO

这导致如下所示:

TicketID  CSV
1         tsql, sqlserver, c++
2         hi, bye, no

现在这很有效,因为我能够直接加入一张桌子...... 现在,我想再次应用STUFF()来显示分配给谁的TicketID。

显示分配了故障单的人的查询如下:

SELECT  l.Login
FROM Ticket t1
LEFT JOIN
    TicketAssignments tass
ON
    tass.TicketID=t1.TicketID
LEFT JOIN
    Login l 
ON
    l.LoginID = tass.LoginID

然而,我错过了两件关键的事情:

1)我需要在第一个示例中显示TicketID(按ticketID分组) 2)我需要STUFF()登录名,以便它以逗号分隔出来

请坚持使用STUFF()我知道有时它可能不是最好的方法,但我只是想在我的代码中使用它。

修改

3桌

Ticket 
------
TicketID

TicketAssignments
-----------------
TicketID
LoginID

Login
------
LoginID

Sample data:

Ticket
------
1
2
3


TicketAssignments
------------------
1   25
1   26
2   25
3   26
3   27

Login
-----
25 Joe
26 Jon
27 Jason

我想要的结果:

TicketID  Assignment
--------------------
    1, "Joe, Jon"
    2, "Joe"
    3, "Jon", "Jason"

那是Joe和Jon被分配了票1 乔被分配了票2 Jon和Jason分配给3号票。

所以STUFF()只是将每个ticketid放在一行中。我知道这效率不高,我现在不要求优化......

如上所述,我必须获得票证分配的查询:

SELECT l.Login     从机票t1     LEFT JOIN         TicketAssignments tass     上         tass.TicketID = t1.TicketID     LEFT JOIN         登录l     上         l.LoginID = tass.LoginID

然而,我错过了两件关键的事情: 1)我需要在第一个示例中显示TicketID(按ticketID分组) 2)我需要STUFF()登录名,以便以逗号分隔出来

3 个答案:

答案 0 :(得分:6)

SELECT t.TicketID, Assignment = STUFF(
(
  SELECT ', ' + l.Name 
    FROM dbo.Login AS l
    INNER JOIN dbo.TicketAssignments AS ta
      ON l.LoginID = ta.LoginID
    WHERE ta.TicketID = t.TicketID
    FOR XML PATH(''), TYPE
).value('.[1]','nvarchar(max)'), 1, 2, '')
FROM dbo.Ticket AS t
ORDER BY t.TicketID;

Demo on SQLFiddle

答案 1 :(得分:2)

STUFF只是删除了您连接标记(或者请求时为login.name)的方式产生的主要逗号。 FOR XML子句实际上是在进行连接工作。

见这个例子:

declare @Ticket table (TicketId int);
insert into @Ticket
    select 1 union all select 2 union all select 3;

declare @TicketAssignments table (TicketId int, LoginId int)
insert into @TicketAssignments
    select 1,25 union all
    select 1,26 union all
    select 2,25 union all
    select 3,26 union all
    select 3,27;

declare @Login table (LoginId int, Name varchar(10));
insert into @Login
    select 25, 'Joe' union all
    select 26, 'Jon' union all
    select 27, 'Jason';


select  ticketId,
        p.n,
        stuff(p.n, 1, 1, '')
from    @Ticket t
cross
apply   (   select  ',' + l.Name
            from    @TicketAssignments ta
            join    @Login l on ta.LoginId = l.LoginId
            where   ta.TicketId = t.TicketId
            for xml path('')
        )p(n)

答案 2 :(得分:0)

以下示例显示如何在两列上应用stuff函数。我有3个按层次顺序排列的表。 作业 - > storejob-> StorejobAssignment。层次结构中的表与外键相关联。 作为JobNo_pk的表Job的主键将作为Jobno_fk作为存储作业表中的外键出现。但是,在StoreJobAssignment表中,JObno_fk不可用,因为它是按层次顺序排列的。

Select Top 10 j.JobNo_pk,
Stuff((select ','+ convert(varchar,StoreJobNo_pk) from Storejob
  where j.JobNo_PK=StoreJob.JobNo_FK  for XML path ('') ),1,1,'') as StorejobNO_pk,

 Stuff((select ','+ convert(varchar,StoreJobAssignmentNo_pk) from StorejobAssignment inner join StoreJob on StoreJob.StoreJobNo_PK=StoreJobAssignment.StoreJobNo_FK
  where StoreJob.Storejobno_pk=StoreJobAssignment.StorejobNo_fk for XML path ('') ),1,1,'') as Storejobassignmnet_pk   

  from job j
  inner join storejob    on j.jobno_pk=StoreJob.jobno_fk 
   inner join StorejobAssignment   on StoreJob.StoreJobno_pk=StoreJobAssignment.Storejobno_fk 
   group by Jobno_pk 

Click here to see the output of the above query