使用SQL查找多对一的值

时间:2017-09-21 19:21:49

标签: sql sql-server

我的问题的第一部分是不知道如何正确地询问和说出这个问题,所以如果这是重复的话我会道歉。

除了用户表,我有一个这样的表

[UserRoles]
UserID | RoleName
-------|---------
1      | Role1
1      | Role2
1      | Role3
1      | Role4
2      | Role1
2      | Role4

另一张像这样的表:

[RoleRoleTypes]
RoleName | Function
-------------------
Role1    | FunctionA
Role2    | FunctionA
Role3    | FunctionB
Role4    | FunctionC

我最终想要的是一个带有UserID的表,一个以逗号分隔的角色列表,一个以逗号分隔的函数列表。

结束结果

UserId | Roles                       | Functions
-------|---------------------------- |------------------------------------
1      | Role1, Role2, Role3, Role4  | FunctionA, FunctionB, FunctionC 
2      | Role1, Role4                | FunctionC

前两列非常简单,使用stuff来创建逗号分隔的角色列表。但是我不确定如何计算一个函数列表,因为多个角色组成了一个函数。用户必须具有列出的所有角色才能拥有该功能。因此,如果您有role1而不是角色2,则您没有FunctionA。我尝试了各种连接,但从未接近正确的数据。有什么建议?

以下是我对前两列的内容

SELECT u.email, Roles = STUFF(
    (SELECT ',' + RoleName
    From UserRoles ur
    WHERE ur.UserID = u.UserID
    FOR XML PATH('')), 1, 1, '')
FROM Users u

编辑添加了澄清和最终结果示例

2 个答案:

答案 0 :(得分:2)

我想您只需要使用类似于RoleNames的方法,并使用distinct来避免重复的功能

SELECT u.userid, 
   Roles = STUFF(
     (SELECT ', ' + RoleName
      FROM UserRoles ur
      WHERE ur.UserID = u.UserID
      FOR XML PATH('')
     ), 1, 1, ''), 
  Functions = STUFF(
     (SELECT distinct ', ' + rt.[function]
      FROM [UserRoles] ur
      JOIN [RoleRoleTypes] rt ON ur.RoleName = rt.RoleName 
      WHERE ur.UserID = u.UserID
      FOR XML PATH('')
     ), 1, 1, '')
FROM [User] u

demo

答案 1 :(得分:0)

您需要在查询中使用 Distinct 关键字,以避免重复结果。