我正在做一个项目,用户需要根据他们所连接的部门获得权限。
所以现在我尝试做一个查询,根据用户 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)。
群组
- 组 CAN(不需要)有很多权限 (groups_permissions)。
重要的边注
departments_permissions、categories_permissions 和 groups_permissions 可以包含一个或多个相同的 permission_id,因此我们必须选择不同的值。
示例数据
我最近的查询尝试:
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;
最佳答案
建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)
关于MySQL JOIN/UNION DISTINCT 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57307502/