2014-10-09 77 views
0

我有一张表人,一张表权限和一个表操作。许可是为了提供People和Action之间的多对多关系。双外连接

我的目标很简单:我想在人员中寻找一个人,我想看到Permission中列出的许可,并且每个可用的操作都可以,无论这个人是否有权限。

请注意,在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 

不过,我可以“T似乎执行双重外部联接我想这将让我的一切:

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

我有些困惑:“我有一张桌子People,一个表格权限和一个表格Action。Interdiction是为了提供人与出版物之间的多对多关系。” - 这不应该是“权限”而不是“发布”吗? – 2014-10-09 08:26:17

+0

您可以发布架构和示例数据吗?你的查询没有加入到Action中,所以我不知道它是如何返回你列出的列标题的...... SQLFiddle会很棒。 – 2014-10-09 08:27:23

+0

@FrankSchmitt:权限和不停止,行动和不公布。我修好了,对不起!我按照Neville的建议添加了一个小提琴。 – Raveline 2014-10-09 08:40:52

回答

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' 
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' 
+0

交叉加入!这就是我想念的!谢谢 ! – Raveline 2014-10-09 09:20:10