我有三张桌子:
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;
给了我一个带有错误数据的交叉连接。
我正在寻找的是如何编写查询以产生我想要的输出的提示。
答案 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