2017-04-22 61 views
0

所有行可以说我有两个表:选择所有阵列值出现在另一列

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

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

我希望能够查询特定用户可以访问所有的集成。我一直在寻找一段时间,但对于在这个范围内使用mysql我相当陌生。

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

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

+0

你有控制表结构吗?我的意思是,你可以创建一个不同的表格吗? –

+0

因此在你的例子中,user_id 1会有整合1,2,3,user_id 2会有1? –

+0

@P.Salmon是的,这是正确的。 :) – Jed

回答

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)