将多个返回从连接转换为单个逗号分隔列表

时间:2017-03-18 20:26:08

标签: sql sql-server

我有这个问题:

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,但我似乎找不到合适的组合。

3 个答案:

答案 0 :(得分:4)

您可以使用XML字符串执行此操作,因为您可以看到Google“SQL Server字符串聚合”。

在您的情况下,由于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;

这里的要点是你不想在外部查询中进行聚合,如果可以避免的话。相反,它使用相关的子查询。

注意:这不是完全等效的,因为它将返回没有角色的用户。

答案 1 :(得分: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

答案 2 :(得分:0)

另一种检索具有角色的 ASPNetUsers 的方法

const [urlList, setUrlList] = useState(0);

const callDayList = () =>{ 
       Axios.post('http://localhost:3001/api/get',{    
       passNum :urlList,
     });
};
useEffect(callDayList,[urlList]);