2016-02-23 40 views
0

我有一个有特定角色的用户表。一个用户每次为他们拥有的角色进入表格。我需要计算具有特定角色的所有用户,但我需要排除也有另一个角色的任何重复记录。下面是什么在我的表如果重复记录具有一定的值,则排除记录

Name Role 
Steve ROLE_8 
Steve ROLE_9 
Steve ROLE_1 

填充,这是查询我要选择谁拥有某些角色的用户。我需要做的是检查用户是否有ROLE_1,并检查是否有另一个用户实例具有我不想包含该用户并将其从返回集中排除的角色。

SELECT COUNT(DISTINCT c.user_id) 
FROM users c 
WHERE email_addr != '' 
AND email_addr IS NOT NULL 
AND EXISTS 
(SELECT r.role_id 
FROM ROLE r, user_role ur 
WHERE c.user_id = ur.user_id 
    AND ur.role_id = r.role_id 
    AND (r.name = 'ROLE_1' 
     OR r.name = 'ROLE_2' 
     OR r.name = 'ROLE_3' 
     OR r.name = 'ROLE_4' 
     OR r.name = 'ROLE_5' 
     OR r.name = 'ROLE_6')) 
+1

你可以显示你想要的输出的例子吗? – GabrielVa

+0

如果我只搜索角色1到6的用户,并且用户在数据库中有两条记录,一条使用ROLE_1,另一条使用ROLE_8,那么我希望从返回集中完全排除该用户。所以在我给的例子中,我想返回0条记录,但因为每条记录都有一个独特的角色,我得到1(因为我选择不同)。 –

回答

1

使用您的COUNTDISTINCT使得EXISTS不必要的 - 你可以加入到user_role表。在这一点上,你只需要排除那些谁也有一个角色,你不希望用户:

SELECT 
    COUNT(DISTINCT U.user_id) 
FROM 
    Users U 
INNER JOIN User_Role UR ON UR.user_id = U.user_id AND 
INNER JOIN Role R ON 
    R.role_id = UR.role_id AND 
    R.name IN ('ROLE_USER_ADMIN', 'ROLE_1'...) 
WHERE 
    U.email_addr IS NOT NULL AND U.email_addr <> '' AND 
    NOT EXISTS 
    (
     SELECT * 
     FROM 
      User_Role UR2 
     INNER JOIN Role R2 ON 
      R2.role_id = UR2.role_id AND 
      R2.name IN ('Some_Excluded_Role') 
     WHERE 
      UR2.user_id = U.user_id 
    ) 

如果要排除谁拥有任何角色列表之外,那么任何用户你可以做到以下几点:

SELECT 
    COUNT(DISTINCT U.user_id) 
FROM 
    Users U 
INNER JOIN User_Role UR ON UR.user_id = U.user_id AND 
INNER JOIN Role R ON 
    R.role_id = UR.role_id AND 
    R.name IN ('ROLE_USER_ADMIN', 'ROLE_1'...) 
WHERE 
    U.email_addr IS NOT NULL AND U.email_addr <> '' AND 
    NOT EXISTS 
    (
     SELECT * 
     FROM 
      User_Role UR2 
     INNER JOIN Role R2 ON 
      R2.role_id = UR2.role_id AND 
      R2.name NOT IN ('ROLE_USER_ADMIN', 'ROLE_1'...) 
     WHERE 
      UR2.user_id = U.user_id 
    ) 
+1

将此标记为正确,因为这是我测试过的第一个答案,并且这两个示例均为我提供了预期结果。非常感谢!如果我应该为未来的读者扩展我的问题,请告诉我。 –

0

我相信这会让你找到你想要的东西(不知道你期望的结果是什么样子)。这个概念首先要找到与“好”角色相匹配的概念,然后用另一个子过滤选择那些也具有“坏”角色的概念。

SELECT COUNT(DISTINCT c.[user_id]) 
FROM users AS c 
    INNER JOIN user_role AS ur 
     ON ur.[user_id] = c.[user_id] 
WHERE c.email_addr != '' 
    AND c.email_addr IS NOT NULL 
    AND ur.role_id IN 
     (SELECT sub_r.role_id 
     FROM [role] AS sub_r 
     WHERE sub_r.name IN ('ROLE_USER_ADMIN', 'ROLE_1') 
     ) 
    AND c.[user_id] NOT IN 
     (SELECT sub2_ur.[user_id] 
     FROM user_role AS sub2_ur 
      INNER JOIN [role] AS sub2_r 
       ON sub2_r.role_id = sub2_ur.role_id 
     WHERE sub2_r.name IN ('ROLE_NOT_TO_USE','ANOTHER_NOT_TO_USE') 
      AND sub2_ur.[user_id] = c.[user_id] 
     ) 
0

如果我想获得一个数据集在我包括具有两种角色1,2或3的用户,我想排除有作用,4和5的用户,我如果“姓名”是唯一的,则会执行以下操作:

SELECT COUNT(DISTINCT Name) 
FROM ROLE 
WHERE Role IN ('ROLE_1','ROLE_2','ROLE_3') 
AND Name NOT IN (SELECT DISTINCT Name FROM ROLE WHERE Role IN ('ROLE_4','ROLE_5');