2014-10-09 1 views
0

나는 테이블이 있습니다. 사람, 테이블 권한 및 테이블 동작. 사람과 행동 사이에 다 - 대 - 다 관계를 제공 할 수있는 권한이 있습니다.이중 외부 조인

목표는 간단합니다. 나는 사람에서 한 사람을 찾고 싶습니다. 권한에 나열된 권한을보고 싶습니다. 사용 가능한 모든 작업은 권한이 있습니다.

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 |   |   | Launching missiles  | 
| John |   |   | Deleting codes   | 
| John |   |   | (every other actions) | 
+-----------------------------------------------------------+ 

:

+-----------------------------------------+ 
+ Name | People_id | Action_id |Action | 
+-----------------------------------------+ 
| John |   |   |  | 
+-----------------------------------------+ 

내가 원하는 때 : 즉

, 결과는 어떤 모습? 그렇다면 어떻게 할 수 있습니까? (저는 PostgreSQL을 사용하고 있습니다).

편집는 : 여기 sqlfiddle입니다 : http://sqlfiddle.com/#!2/6d502

+0

나는 다소 혼란 스럽다 : "나는 사람 테이블, 테이블 권한 및 테이블 액션이있다. 차단은 사람과 출판물 사이에 다 - 대 - 다 관계를 제공한다." - "간행물"대신에 "허가"가되어서는 안됩니까? –

+0

스키마 및 샘플 데이터를 게시 할 수 있습니까? 귀하의 쿼리는 Action에 가입하지 않으므로 목록의 열 머리글이 어떻게 반환되는지는 알 수 없습니다. SQLFiddle은 훌륭합니다. –

+0

@FrankSchmitt : 금지 및 금지 사항, 게시 및 게시 금지. 나는 그것을 고쳤다. 미안하다! 네빌이 제안한대로 바이올린을 추가했습니다. – Raveline

답변

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