代码之家  ›  专栏  ›  技术社区  ›  Ed Sinek

SQL:从单个查询中列出多对多

  •  2
  • Ed Sinek  · 技术社区  · 14 年前

    我有3个表代表“用户”、“角色”和多对多“用户角色”-带有键:userid、roleid;相关列:username、rolename

    在管理HTML应用程序中,我想显示所有用户及其角色的列表。在SQL中,我试图构造一个返回此信息的查询。角色列表应该被分隔,这样我就可以进行适当的表示操作(取决于表示平台,比如用br标记替换分隔符)。

    为用户列表使用一个select,然后为每个用户单独选择以获得角色是直接的,但是尝试构建一个输出下面内容的select,这让我很困惑。

    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
    
    3 回复  |  直到 14 年前
        1
  •  3
  •   John Raymund    13 年前

    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
    
        2
  •  2
  •   OMG Ponies    14 年前

    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
    
        3
  •  0
  •   Dan J    14 年前