删除重复的表单选择结果

时间:2019-09-21 08:20:14

标签: mysql sql

#edited

好的。我将删除所有角色权限,然后再次添加。

是否可以将所有4个查询合并为一个?


我正在创建权限系统。

假设:

  • 每个用户可以拥有多个角色

  • 每个角色可以拥有多个权限

  • 权限也可以直接分配给用户(它们的优先级高于角色的权限)

权限的优先级是:

  • 角色权限

  • 拒绝角色

  • 用户权限

  • 拒绝用户

拒绝用户具有最高优先级


PHP的问题很简单:

  • 我创建具有所有权限的数组

  • 我正在获得角色的权限(按访问权限排序)

  • 我分配访问权限,如果被拒绝,我将使用拒绝访问覆盖访问权限

  • 我对用户权限也是如此

  • 我分配访问权限,如果被拒绝,我将使用拒绝访问覆盖访问权限

这样,我拥有整个阵列,并具有特定用户的权限,例如$ user ['permission'] ['delete_post'] //输出:false ||是

我现在需要进行权限检查。这意味着哪个用户可以访问例如'delete_post'

我有这个数据库结构: DB structure 这里摆弄数据库:DB fiddle

我对第一个查询有疑问

**Query #1**
    =============================================
        List of all roles related to permission with id 3   */
    SELECT DISTINCT role_id, access, permission_id FROM role_permissions WHERE permission_id=3 ORDER BY role_id, access DESC;

| role_id | access | permission_id |
| ------- | ------ | ------------- |
| 5       | 0      | 3             |
| 8       | 1      | 3             |
| 10      | 1      | 3             |
| 10      | 0      | 3             |

我应该得到

| role_id | access | permission_id |
| ------- | ------ | ------------- |
| 8       | 1      | 3             |

我无法添加WHERE permission_id=3 AND access=1,因为我得到的结果是:rol​​e_id = 8和role_id = 10,但是role_id = 10确实没有访问权限。

2 个答案:

答案 0 :(得分:1)

一种方法是根据各个表之间的关系进行所有适当的联接,然后使用带有GROUP BY子句的HAVING进行基于聚集的过滤。

以下查询将为您提供所有具有给定权限ID允许访问权限的用户(以下查询中的注释中有更多解释-可能需要对逻辑有更多了解;如果需要,请进行检查和注释):

查询-View on DB Fiddle

SELECT 
  u.user_id, 
  u.name 
FROM users AS u 
-- Left Join to get access (if defined for input permission id)
LEFT JOIN user_permissions AS up
  ON up.user_id = u.user_id 
     AND up.permission_id = 3 
-- Join to Roles; assuming every user has atleast one role
-- Change this to LEFT JOIN if it is possible that user can have NO role
JOIN user_roles AS ur 
  ON ur.user_id = u.user_id 
-- Left Join to get access defined for input permission id for roles
LEFT JOIN role_permissions AS rp 
  ON rp.role_id = ur.role_id 
     AND rp.permission_id = 3
GROUP BY u.user_id, u.name 
HAVING 
  -- first priority if user specific access allowed
  -- if data is sane then up.access will have same value 
  -- across all rows in a group for user
  MAX(up.access) = 1 

  OR 

  -- second priority is not have a single role with 
  -- denied permission AND 
  -- atleast one role exists with allowed permission
  ( NOT SUM(rp.access = 0) 
    AND 
    SUM(rp.access = 1)
  );

结果

| user_id | name             |
| ------- | ---------------- |
| 4       | Cyrus Gomez      |
| 7       | MacKensie Morton |
| 13      | Nadine Taylor    |
| 15      | Ezekiel Bonner   |
| 17      | Ciaran Turner    |
| 35      | Olga Dominguez   |
| 38      | Lucas Pierce     |

答案 1 :(得分:0)

您可以如下添加WHERE条件-

SELECT DISTINCT role_id, access, permission_id 
FROM role_permissions 
WHERE permission_id=3 
AND role_id NOT IN (
    SELECT DISTINCT role_id  
    FROM role_permissions
    WHERE access = 0
    AND permission_id=3  -- New condition added
)
ORDER BY role_id, access DESC;