Sql 双外接头

Sql 双外接头,sql,postgresql,outer-join,Sql,Postgresql,Outer Join,我有一个表人员、表权限和表操作。允许在人与行为之间提供多对多关系 我的目标很简单:我想在People中查找一个人,我想查看permission中列出的权限,以及所有可用的操作,无论此人是否拥有权限 请注意,权限中不需要表示人员的成员。所以,“John”只有在获得数据库中写入的权限的情况下才被允许做一些事情 理想情况下,结果如下所示: +-------------------------------------------+ + People.name | Action.name |

我有一个表人员、表权限和表操作。允许在人与行为之间提供多对多关系

我的目标很简单:我想在People中查找一个人,我想查看permission中列出的权限,以及所有可用的操作,无论此人是否拥有权限

请注意,权限中不需要表示人员的成员。所以,“John”只有在获得数据库中写入的权限的情况下才被允许做一些事情

理想情况下,结果如下所示:

+-------------------------------------------+
+ People.name | Action.name        |Allowed |
+-------------------------------------------+
| John Doe    | Launching missiles | N      |
| John Doe    | Deleting code      | Y      |
+-------------------------------------------+
+-----------------------------------------+
+ Name    | People_id | Action_id |Action |
+-----------------------------------------+
| John    |           |           |       |
+-----------------------------------------+
在开始之前,我只是尝试用每个数据构建一个简单的查询。 获取某人的权限列表很容易,即使他不在权限表中:

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.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'
向约翰展示了他没有得到许可的事实。。。但没有任何行动

换句话说,结果类似于:

+-------------------------------------------+
+ People.name | Action.name        |Allowed |
+-------------------------------------------+
| John Doe    | Launching missiles | N      |
| John Doe    | Deleting code      | Y      |
+-------------------------------------------+
+-----------------------------------------+
+ Name    | People_id | Action_id |Action |
+-----------------------------------------+
| John    |           |           |       |
+-----------------------------------------+
当我想要的时候:

+-----------------------------------------------------------+
+ Name    | People_id | Action_id |Action                   |
+-----------------------------------------------------------+
| John    |           |           | Launching missiles      |
| John    |           |           | Deleting codes          |
| John    |           |           | (every other actions)   |
+-----------------------------------------------------------+
那么,我想要的可能吗?如果是的话,我怎样才能做到呢?(我正在使用PostgreSQL)

编辑:下面是一个SQLFIDLE:

SQLFiddle:

要按人名筛选,请添加到查询:

WHERE pp.name = 'John'
SQLFiddle:

要按人名筛选,请添加到查询:

WHERE pp.name = 'John'
SQLFiddle:

要按人名筛选,请添加到查询:

WHERE pp.name = 'John'
SQLFiddle:

要按人名筛选,请添加到查询:

WHERE pp.name = 'John'
这应该行得通

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'
这应该行得通

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'
这应该行得通

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'
这应该行得通

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'

我有点困惑:“我有一个表People、一个表Permission和一个表Action。禁止是为了提供人和发布之间的多对多关系。”-这不应该是“Permission”而不是“Publication”?你能发布一个模式和示例数据吗?您的查询没有连接到操作,因此我看不出它如何返回您列出的列标题…SQLFIDLE会很好。@FrankSchmitt:权限而不是禁止,操作而不是发布。我已经修好了,对不起!正如Neville建议的那样,我添加了一把小提琴。我有点困惑:“我有一个表People,一个表Permission和一个表Action。阻拦是为了提供人和发布之间的多对多关系。”-这不应该是“Permission”而不是“Publication”?你能发布一个模式和示例数据吗?您的查询没有连接到操作,因此我看不出它如何返回您列出的列标题…SQLFIDLE会很好。@FrankSchmitt:权限而不是禁止,操作而不是发布。我已经修好了,对不起!正如Neville建议的那样,我添加了一把小提琴。我有点困惑:“我有一个表People,一个表Permission和一个表Action。阻拦是为了提供人和发布之间的多对多关系。”-这不应该是“Permission”而不是“Publication”?你能发布一个模式和示例数据吗?您的查询没有连接到操作,因此我看不出它如何返回您列出的列标题…SQLFIDLE会很好。@FrankSchmitt:权限而不是禁止,操作而不是发布。我已经修好了,对不起!正如Neville建议的那样,我添加了一把小提琴。我有点困惑:“我有一个表People,一个表Permission和一个表Action。阻拦是为了提供人和发布之间的多对多关系。”-这不应该是“Permission”而不是“Publication”?你能发布一个模式和示例数据吗?您的查询没有连接到操作,因此我看不出它如何返回您列出的列标题…SQLFIDLE会很好。@FrankSchmitt:权限而不是禁止,操作而不是发布。我已经修好了,对不起!我按照内维尔的建议加了一把小提琴。交叉连接!这就是我错过的!非常感谢。交叉连接!这就是我错过的!非常感谢。交叉连接!这就是我错过的!非常感谢。交叉连接!这就是我错过的!非常感谢。