MySQL JOIN / UNION DISTINCT 问题

MySQL JOIN / UNION DISTINCT issue

我正在做一个项目,用户需要根据他们所连接的部门获得权限。

所以现在我正在尝试做一个查询,根据用户 department_id 向我显示拥有所有必要权限的用户(结果中不会显示没有所有必要权限的用户) .

我一直在尝试很多不同的事情(不同类型的 JOINS、子查询 w/where in、exists 和 union distinct)但运气不佳,这种查询对我来说是下一个级别并挑战我的逻辑思维.

表格:

users
    id
    first_name
    last_name
    department_id

permissions
    id
    name

departments (relation to groups and categories based on department)
    id 
    name
    category_id
    group_id

categories
    id
    name

groups
    id
    name

departments_permissions (permission requirement)
    department_id
    permission_id

categories_permissions (permission requirement)
    category_id
    permission_id

groups_permissions (permission requirement)
    group_id
    permission_id

users_permissions (users have permissions here)
    user_id
    permission_id

部门

类别

重要旁注

departments_permissions、categories_permissions 和 groups_permissions 可以包含一个或多个相同的 permission_id,因此我们必须 select 不同的值。

示例数据

https://pastebin.com/BvhAznpY

我最近的查询尝试:

SELECT 
    `users`.id, 
    `users`.first_name, 
    `users`.last_name,
    `users`.department_id
FROM 
    `users`
INNER JOIN 
    `departments` ON `users`.department_id = `departments`.id 
INNER JOIN 
    `users_permissions` ON `users`.id = `users_permissions`.user_id 
INNER JOIN 
    (
        SELECT permission_id FROM departments_permissions WHERE department_id = departments.id
        UNION DISTINCT
        SELECT permission_id FROM categories_permissions WHERE category_id = departments.group_id
        UNION DISTINCT
        SELECT permission_id FROM groups_permissions WHERE group_id = departments.group_id
    ) AS tblPermissionsRequired ON `users_permissions`.permission_id = `tblPermissionsRequired`.permission_id
GROUP BY 
    `users_permissions`.user_id;

我想你需要的是这样的:

SELECT u.first_name,u.last_name,p.name
FROM users u, user_permissions up, permissions p
WHERE u.id=up.user_id AND
up.permission_id=p.id
UNION
SELECT u.first_name,u.last_name,p.name
FROM users u, departments d, departments_permission dp, permissions p
WHERE u.department_id=d.id
AND d.id=dp.department_id
AND dp.permission_id=p.id
UNION
SELECT u.first_name,u.last_name,p.name
FROM users u, departments d, categories_permission cp, permissions p
WHERE u.department_id=d.id
AND d.category_id=cp.category_id
AND cp.permission_id=p.id
UNION
SELECT u.first_name,u.last_name,p.name
FROM users u, departments d, groups_permission gp, permissions p
WHERE u.department_id=d.id
AND d.group_id=gp.group_id
AND gp.permission_id=p.id

这里有一个提示:

  • 使用上面的查询创建一个视图
  • 在视图上执行 SELECT DISTINCT *

建立2个表(子查询)列出

  • 用户需要的所有权限(即user_permissions)
  • 用户拥有的所有权限(即与您所做的类似的 3 个联合)

加入他们并按 id 分组将找到所需的数量以及已经给出的数量。

最后,添加一个过滤子句(使用HAVING)。然后你得到了用户 ID 列表:)

select
  up.user_id,
  max(u.first_name) as first_name,
  max(u.last_name) as last_name,
  count(up.permission_id) as permission_required,
  count(perm.permission_id) as permission_have
from
  users u
join
  users_permissions up on u.id = up.user_id
left join
(
  SELECT users.id as user_id, permission_id
  FROM users
  INNER JOIN departments ON users.department_id = departments.id
  INNER JOIN departments_permissions on departments_permissions.department_id = departments.id

  UNION

  SELECT users.id, permission_id
  FROM users
  INNER JOIN departments ON users.department_id = departments.id
  INNER JOIN categories_permissions on categories_permissions.category_id = departments.category_id

  UNION

  SELECT users.id, permission_id
  FROM users
  INNER JOIN departments ON users.department_id = departments.id
  INNER JOIN groups_permissions  on groups_permissions.group_id = groups_permissions.group_id
) perm
on up.user_id = perm.user_id and up.permission_id = perm.permission_id
group by up.user_id
having count(up.permission_id)  = count(perm.permission_id)

下面的脚本应该可以工作-

SELECT A.id,A.first_name,A.last_name,A.department_id 
FROM
(
    SELECT U.*,
    A.Dept_id AS Dept_ID,
    A.permission_id AS [Dept_Wise_Permissiion_List],
    UP.permission_id
    FROM users U
    INNER JOIN (
            SELECT D.id Dept_id,CP.permission_id  
            FROM departments D INNER JOIN categories_permissions CP ON D.category_id = CP.category_id 

            UNION ALL

            SELECT D.id Dept_id,GP.permission_id  
            FROM departments D INNER JOIN groups_permissions GP ON D.group_id = GP.group_id

            UNION ALL

            SELECT D.id Dept_id, DP.permission_id
            FROM departments D INNER JOIN departments_permissions DP ON D.id = DP.department_id

    ) A ON U.department_id =A. Dept_id
    LEFT JOIN users_permissions UP 
        ON U.id = UP.user_id AND A.permission_id = UP.permission_id
)A
GROUP BY A.id,A.first_name,A.last_name,A.department_id 
HAVING COUNT(ISNULL(A.permission_id,1)) = COUNT(A.permission_id)