2017-03-18 43 views
2

我有這個疑問:轉換多個恢復從連接到一個逗號分隔的列表

SELECT 
    c.FirstName + ' ' + c.LastName AS Name, 
    r.Name AS Roles 
FROM 
    Contacts c 
    JOIN AspNetUsers u on c.ContactID = u.ContactID 
    JOIN AspNetUserRoles ur on u.id = ur.UserId 
    JOIN AspNetRoles r on ur.RoleId = r.Id 

返回一組是這樣的:

Name  Roles 
----------------------- 
Bob Jones Admin 
Bob Jones Agent 
Jane Smith Broker 
Jane Smith Buyer 

我想是這樣的:

Name  Roles 
----------------------- 
Bob Jones Admin, Agent 
Jane Smith Broker, Buyer 

我一直在玩COALESCEGroupBy,但我似乎無法得到正確的組合。

回答

2

另一種方法是將在CTE原始查詢,然後創建了最後的總結

;with cte as (
    SELECT 
     c.FirstName + ' ' + c.LastName AS Name, 
     r.Name AS Roles 
    FROM 
     Contacts c 
     JOIN AspNetUsers u on c.ContactID = u.ContactID 
     JOIN AspNetUserRoles ur on u.id = ur.UserId 
     JOIN AspNetRoles r on ur.RoleId = r.Id 
) 
Select A.Name 
     ,Roles = Stuff((Select Distinct ', ' +Roles From cte Where Name=A.Name For XML Path ('')),1,2,'') 
From (Select Distinct Name from cte) A 
+0

謝謝!問題...對於這篇文章的相同,我刪除了最終結果中需要的一些字段。我無法弄清楚如何將它們添加到您的查詢中。假設我還需要聯繫人表中的c.ContactID和c.Email? –

+1

@CaseyCrookston in final FROM(從cte中選擇Distinct ContactID,Name,Email)A –

4

您可以使用XML字符串執行此操作,就像您可以看到Google是「SQL Server string aggregate」一樣。

在你的情況下,查詢可能不明顯,因爲JOIN s。我覺得這是最好的辦法:

SELECT c.FirstName + ' ' + c.LastName AS Name, 
     STUFF((SELECT ',' + r.Name 
       FROM AspNetUsers u JOIN 
        AspNetUserRoles ur 
        ON u.id = ur.UserId JOIN 
        AspNetRoles r 
        ON ur.RoleId = r.Id 
       WHERE c.ContactID = u.ContactID 
       FOR XML PATH (''), TYPE 
      ).VALUE('.', 'nvarchar(max)' 
        ), 1, 1, '') 
      as Roles 
FROM Contacts c; 

這裏的關鍵是,你不想做聚集在外部查詢,如果你能避免它。相反,它使用相關的子查詢。

注意:這不是正好等於,因爲它會返回沒有角色的用戶。

+0

非常感謝!我正在測試。似乎缺少一個逗號或打開或關閉()。 –

+0

@CaseyCrookston刪除了額外的右括號,現在就試試。 – SqlZim

相關問題