MySQL JOIN/UNION DISTINCT 问题

标签 mysql sql join union distinct

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

所以现在我尝试做一个查询,根据用户 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,因此我们必须选择不同的值。

示例数据

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;

最佳答案

建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/

相关文章:

mysql - 数据库查询 - 按两个值排序(嵌套顺序)

php - 如何在 PHP 中使用左连接数据将数据从映射器保存到实体

mysql - 通过链接的 MySQL 数据库更新 MySQL 数据库的 MSSQL

mysql - SQL - 选择至少包含一个 NULL 值的列?

mysql - 提示用户在 MySQL 中输入一个变量

c# - 连接来自 IQueryable 和 IList<KeyValuePair> 的数据

MySQL 从多个表中查询一个值

PHP die() 函数会断开 mysql 的连接吗?

mysql - 速度选择与加入

mysql - 如何做这个查询?