如何使这个(LEFT?)JOIN工作

时间:2011-11-07 03:15:23

标签: postgresql

我有三张桌子:

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 JOIN,但是当我试图实现我想要的时候,我会努力工作:

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;

给了我一个带有错误数据的交叉连接。

我正在寻找的是如何编写查询以产生我想要的输出的提示。

3 个答案:

答案 0 :(得分: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

我认为这更接近你想要的。

答案 1 :(得分: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;

答案 2 :(得分: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