3

私はこれを読みました:http://blog.sqlauthority.com/2012/09/14/sql-server-grouping-by-multiple-columns-to-single-column-as-a-string/

そして、これを私のクエリの1つに適用できます。

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

1つのテーブルに直接参加できたので、これは機能しました...次に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

しかし、私は2つの重要なことを見逃しています。

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"

つまり、ジョーとジョンにはチケット1が割り当てられ、ジョーにはチケット2が割り当てられ、ジョンとジェイソンにはチケット3が割り当てられました。

したがって、STUFF()は、それらをチケットIDごとに1つの行にまとめるだけです。私はこれが効率的ではないことを知っています、私は今最適化を求めていません...

前述のように、チケットの割り当てを取得する必要があるクエリは次のとおりです。

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

ただし、2つの重要な点が欠けています:1)最初の例のようにTicketIDを表示する必要があります(ticketIDによるグループ化)2)ログイン名をSTUFF()して、コンマで区切って表示する必要があります

4

3 に答える 3

6

Nathanが説明したように、STUFF()実際には連結を実行していません。これは、先頭のコンマを削除するだけです(IMHOの方が適切です。その後、出力文字列の長さを計算して連結することにより、末尾のコンマを削除する必要があります)。

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

出力:

チケットID 割り当て
1 「ジョー」、「ジョン」
2 「ジョー」
3 「ジョン」、「ジェイソン」

STRING_AGG()SQL Server 2017以降では、を使用でき、これが少し簡単になることに注意してください。

SELECT t.TicketID, 
  Assignment = STRING_AGG(CONCAT('"', l.Name, '"'), ', ')
FROM dbo.Tickets AS t
INNER JOIN dbo.TicketAssignments AS ta
  ON t.TicketID = ta.TicketID
INNER JOIN dbo.Logins AS l
  ON ta.LoginID = l.LoginID
GROUP BY t.TicketID;
于 2013-01-18T19:50:36.690 に答える
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)
于 2013-01-18T19:51:39.857 に答える
0

次の例は、2つの列にスタッフ関数を適用する方法を示しています。階層順に3つのテーブルがあります。Job->storejob->StorejobAssignment。階層内のテーブルは外部キーに関連付けられています。JobNo_pkであるテーブルJobの主キーは、Jobno_fkとしてストアジョブテーブルに外部キーとして存在します。ただし、JObno_fkは階層順になっているため、StoreJobAssignmentテーブルでは使用できません。

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 

上記のクエリの出力を表示するには、ここをクリックしてください

于 2017-09-01T05:25:58.560 に答える