我有一个表People,一个表Permission和一个表Action。允许在人与行动之间提供多对多的关系。
我的目标很简单:我想在People中寻找一个人,我希望看到权限中列出的权限,以及每个可用的操作,无论该人是否拥有权限。
请注意,Permission中不需要表示People的成员。因此,“John”只有在获得数据库中写入的权限时才被允许做某事。
理想情况下,结果看起来像:
+-------------------------------------------+
+ People.name | Action.name |Allowed |
+-------------------------------------------+
| John Doe | Launching missiles | N |
| John Doe | Deleting code | Y |
+-------------------------------------------+
在我到达那里之前,我只想简单地用每个数据构建一个简单的查询。 获取某人的许可列表,即使他没有出现在权限表中也很容易:
SELECT * FROM people pp LEFT OUTER JOIN permission pr ON pp.id = pr.people_id
WHERE pp.name = 'John';
获取权限和操作列表很简单:
SELECT * FROM permission pr LEFT OUTER JOIN action a ON pr.action_id = a.id
然而,我似乎无法执行一个双外连接,可以获得我想要的一切:
SELECT * FROM people pp LEFT OUTER JOIN permission pr ON pp.id = pr.permission_id
LEFT OUTER JOIN people WHERE pp.name = 'John'
显示约翰,事实上他没有得到许可......但没有任何行动。
换句话说,结果看起来像:
+-----------------------------------------+
+ Name | People_id | Action_id |Action |
+-----------------------------------------+
| John | | | |
+-----------------------------------------+
我想要的时候:
+-----------------------------------------------------------+
+ Name | People_id | Action_id |Action |
+-----------------------------------------------------------+
| John | | | Launching missiles |
| John | | | Deleting codes |
| John | | | (every other actions) |
+-----------------------------------------------------------+
那么,我想要的可能吗?如果是这样,我该如何实现呢? (我正在使用PostgreSQL)。
编辑:这是一个sqlfiddle:http://sqlfiddle.com/#!2/6d502
答案 0 :(得分:2)
SELECT pp.name, pr.id_people, pr.id_action, a.name as action_name
FROM people pp
CROSS JOIN action a
LEFT JOIN permission pr
ON pr.id_people = pp.id
AND pr.id_action = a.id
SQLFiddle:http://sqlfiddle.com/#!15/5a7b1/4
按人名过滤添加到查询:
WHERE pp.name = 'John'
答案 1 :(得分:1)
这应该有用。
SELECT
P.name as "people.name",
IFNULL(pm.id_people,''),
IFNULL(pm.id_action,''),
A.name as "action.name"
FROM Action A
CROSS JOIN People P
LEFT JOIN permission pm
ON pm.id_action = a.id
AND pm.id_people = p.id
WHERE p.name = 'John'