选择所有数组值存在于另一列中的所有行

时间:2017-04-22 09:42:30

标签: mysql

假设我有两张桌子:

--------------------------------
| user_id  | permissions        |
---------------------------------
|    1     | ['perm1', 'perm2'] | 
---------------------------------
|    2     | ['perm1']          |
---------------------------------

----------------------------------------
| integration_id | permissions_required |
-----------------------------------------
|       1        |   ['perm1']          |
-----------------------------------------
|       2        |   ['perm2']          |
-----------------------------------------
|       3        |   ['perm1', 'perm2'] |
------------------------------------------

我希望能够查询特定用户有权访问的所有集成。我一直在寻找一段时间,但我在这方面使用mysql相当新。

如何查询这些表以查找用户具有所有必需权限的所有集成?

编辑:我意识到我没有提到权限& permissions_required列是JSON列。基于接受的答案,我将提出重构我们的数据库权限的主题,以使用传统的多个 - >多个而不是数组

1 个答案:

答案 0 :(得分:0)

这是一个明显的例子,说明为什么在单个列中存储逗号分隔值是个坏主意。根据您的设计,您将需要拆分字符串(MySQL甚至没有内置函数),然后根据拆分结果连接表。

在正确设计的表架构上,您想要完成的任务会非常容易。

从头开始,您的实体为userintegrationpermission,因此您需要为每个实体提供一个表格。

User: id, name, whatever_else
Integration: id, description, whatever_else
Permission: id, description, whatever_else

userpermission之间的关系为many-to-many,因为每个user可以有多个permissions,每个permission都可以多个users:你想用另一个表建模这个

UserPermission: userID, permissionID

同样适用于permissionintegration之间的关系:每个integration可能需要多个permissions,每个permission可能需要多个integrations }}

IntegrationPermission: integrationID, permissionID

您的样本数据将如下所示

User
id | name
1  | User1
2  | User2

Permission
id | desc
1  | Perm1
2  | Perm2

UserPermission
userID | permissionID
1      | 1
1      | 2
2      | 1

Integration
id | desc
1  | Integration1
2  | Integration2
3  | Integration3

IntegrationPermission
integrationID | permissionID
1             | 1
2             | 2
3             | 1
3             | 2

现在查询:棘手的部分是让拥有集成所需权限的用户。让我们分几步建立这个。

首先,我们将两个关系表结合起来,以获得用户,集成以及用户对该集成的权限数量

select  t1.userID,
        t2.integrationID,
        count(distinct t2.permissionID) as userIntegrationPermissions
from    userPermission t1
join    integrationPermission t2
on      t1.permissionID = t2.permissionID
group by t1.userID, t2.integrationID

然后,我们需要计算每次集成所需的权限

select  integrationID,
        count(permissionID) permCount
from    integrationPermission
group by integrationID

最后,我们加入这两个,添加用户和集成表来获取描述(当然这是可选的)

select  tt3.id, tt3.name, tt4.id, tt4.desc
from    (
            select  t1.userID,
                    t2.integrationID,
                    count(distinct t2.permissionID) as userIntegrationPermissions
            from    UserPermission t1
            join    IntegrationPermission t2
            on      t1.permissionID = t2.permissionID
            group by t1.userID, t2.integrationID
        ) tt1
join    (
            select  integrationID,
                    count(permissionID) permCount
            from    IntegrationPermission
            group by integrationID
        ) tt2
on      tt1.integrationID = tt2.integrationID and
        tt1.userIntegrationPermissions = tt2.permCount
join    User tt3
on      tt1.userID = tt3.id
join    Integration tt4
on      tt1.integrationID = tt4.id
order by 1, 3

您可以在this link (rextester)

处理它