我有3个表代表“用户”,“角色”和多对多的“UsersInRoles” - 用键:UserId,RoleId; pertinant columns:UserName,RoleName
在admin html应用程序中,我想显示所有用户及其所在角色的列表。从SQL,我正在尝试构建一个将返回此信息的查询。应该分隔角色列表,以便我可以进行适当的演示操作(取决于演示平台,例如用BR标记替换分隔符)。
对用户列表使用一个选择,然后为每个用户单独选择以获得角色是直截了当的,但是尝试构建输出以下内容的单个选择让我感到难过。
UserId UserName Roles
------ -------- -----
1 user1 Admin,Guest,PowerUser
2 user2 Guest
3 user3
4 user4 PowerUser,Guest
提前致谢,
--ed
- 编辑 -
现在使用以下查询(感谢所有人,尤其是Raymund& his blog):
WITH RolesList AS
(
SELECT u.UserName,
(
SELECT r.RoleName + ',' AS 'data()'
FROM Roles r
JOIN UsersInRoles ur ON ur.RoleId = r.RoleId
WHERE ur.UserId = u.UserId FOR XML PATH('')
) AS RolesCSV
FROM Users u
) SELECT UserName, LEFT(RolesCSV, LEN(RolesCSV)-1) AS RolesCSV FROM RolesList
答案 0 :(得分:3)
继承你的解决方案:
Converting / Parsing Rows to Delimited string column in SQL
修改强>
如果您需要进一步明确,请回答
WITH UserList as
(
SELECT UserID, UserName,
(SELECT
RoleName + ',' AS 'data()'
FROM Roles
INNER JOIN
UsersInRoles
ON
Roles.RoleID = UsersInRoles.RoleID
WHERE
UsersInRoles.UserID = Users.UserID FOR XML PATH('')) AS RoleCSV
FROM Users
)
SELECT UserID, UserName, LEFT(RoleCSV, LEN(RoleCSV)-1) as RoleCSV from UserList
答案 1 :(得分:2)
SELECT u.user_id,
u.username,
STUFF(ISNULL(SELECT ', ' + r.role_name
FROM USERSINROLES uir
JOIN ROLES r ON r.role_id = uir.role_id
WHERE uir.user_id = u.user_id
GROUP BY r.role_name
FOR XML PATH ('')), ''), 1, 2, '')
FROM USERS u
答案 2 :(得分:0)
由于@OMG小马指出我原来的“转动”反应不符合这个问题的标记,让我推迟他的解决方案。但是,我还是想提一个替代方案:
应该分隔角色列表 所以我可以做到合适 演示操作(取决于 在演示平台上,如替换 带有BR标签的分隔符。)
如果您正在提供分隔符,那么您的表示层可以(可能)将组合值分开,为什么不将它们单独返回,或者只返回加入多对多表的结果(留下一堆重复项),只需在表示层处理结果?
有两个论点:
在你的情况下,这些都不是令人信服的,但我希望我提供了深思熟虑的食物。