2011-11-07 4 views
0

나는 세 개의 테이블이있어 가입 :

CREATE TABLE credential_types (
    id serial PRIMARY KEY, 
    name varchar(32) NOT NULL, 
    ... 
); 

CREATE TABLE credentials (
    user_id integer REFERENCES users(id), 
    credential integer REFERENCES credential_types(id), 
    UNIQUE (user_id, credential) 
); 

CREATE TABLE users (
    id serial PRIMARY KEY, 
    name varchar(64), 
    username varchar(64), 
    ... 
); 

지금, 내가 존재하는 모든 사용자를 가져 오려는을, 그리고 나는 그들이 가지고있는 특정 자격 증명 유형을 가져 싶다. 나는 이것을 시도했다 :

ribit=> SELECT u.id, u.name, u.username, ct.name AS cred \ 
     FROM users u, credential_types ct, credentials c \ 
     WHERE c.user_id=u.id AND ct.id=c.credential; 
id | name | username | cred 
----+------+----------+--------- 
    1 | foo | bos  | Try-Out 
(1 row) 

올바른 종류의 출력이지만 아직 자격 증명 (null)이없는 모든 사용자는 빠져있다. 이 작업을 위해 어떤 종류의 JOIN이 필요한지 알 수 없습니다. 나는 내가 LEFT 필요이 가입 생각 ,하지만 난 내가 원하는 것을 달성 할 때 열심히 실패 :

ribit=> SELECT u.id, u.name, u.username, ct.name \ 
     FROM users u, credential_types ct \ 
     LEFT JOIN credentials c ON ct.id=c.credential; 

나에게 크로스 erronious 데이터와 결합을 제공합니다.

내가 찾고있는 출력을 생성하기 위해 쿼리를 작성하는 방법에 대한 힌트가 있습니다.

답변

0

왼쪽 결합이 적절한 위치에 있지 않습니다.

SELECT u.id, u.name, u.username, ct.name 
FROM users u 
LEFT JOIN credentials c ON u.id = c.user_id 
INNER JOIN credential_types ct ON c.credential = ct.id 

나는 이것이 당신이 원하는 것과 더 가깝다고 생각합니다.

+0

그 중 하나가 거의 효과가있었습니다. 즉, 내 "작동하는"쿼리처럼 작동하지만 내부 조인을 LEFT JOIN (즉, LEFT JOIN)으로 변경하면 노력하고있는 출력을 생성합니다. 그러나, 나는 왜 또는 무슨 일이 일어나고 있는지 모르므로 PG 매뉴얼에 다시 한번 들어가야 할 것입니다. 감사합니다. – bos

+0

두 개의 왼쪽 조인이 작동하면 좋습니다. 유일한 이론적 인 차이점은 'credential_types'에서 일치하지 않는 경우'credentials'의 행이 일치하지 않을 것이라는 것입니다. 이는 외부 키 제약 조건을 고려할 때 가능하지 않습니다. 두 경우 모두 왼쪽 조인은이 경우에 잘되어야합니다. – Andrew

0

당신은 자격 증명 테이블을 조인 먼저 시도하고 그 결과를 사용자 테이블을 조인 왼쪽으로 수

SELECT u.id, u.name, u.username, ct.name 
FROM users u 
LEFT JOIN credentials c ON (u.id=c.user_id) 
JOIN credential_type ct ON ct.id=c.credential; 
0

을보십시오.

SELECT u.id, u.name, u.username, cred 
FROM users u LEFT JOIN 
(SELECT ct.name AS cred, c.user_id 
    FROM credentials c JOIN credential_types ct ON c.credential=ct.id 
) ON u.id=c.user_id