我的表格看起来像这样
Table 1 Table 2 Users Options id name id user_id option ------- --- -------- -------- 1 Donald 1 1 access1 2 John 2 1 access2 3 Bruce 3 1 access3 4 Paul 4 2 access1 5 Ronald 5 2 access3 6 Steve 6 3 access1
现在,我想选择加入这些,以找到只有 access1 的用户 如果我做了类似
的事情select t1.id,t1.name,t2.id,t2.user_id,t2.option
from table1 t1, table2 t2
where t1.id=t2.user_id
and option='access1';
这并没有给我独特的结果,因为在我只需要 user_id = 3 的示例中,我的数据有数百个这样的
我也试过像
这样的东西select user_id from table2 where option='access1'
and user_id not in (select user_id from table2 where option<>'access1')
还有其他不成功的尝试,但我被困在这里
答案 0 :(得分:2)
您可以使用EXISTS子查询(技术上,左半连接)来执行此操作:
SELECT id, name
FROM table1
WHERE EXISTS(
SELECT * FROM table2
WHERE table1.id = table2.user_id
AND table2.option = 'access1'
)
如果您只想要具有access1而不是任何其他访问权限的用户,请添加NOT EXISTS(左侧反半连接;这是一个让您的同事留下深刻印象的术语!):
AND NOT EXISTS (
SELECT * FROM table2
WHERE table1.id = table2.user_id
AND table2.option <> 'access1'
)
答案 1 :(得分:1)
bool_and
简化了
with users (id,name) as ( values
(1,'donald'),
(2,'john'),
(3,'bruce'),
(4,'paul'),
(5,'ronald'),
(6,'steve')
), options (id,user_id,option) as ( values
(1,1,'access1'),
(2,1,'access2'),
(3,1,'access3'),
(4,2,'access1'),
(5,2,'access3'),
(6,3,'access1')
)
select u.id, u.name
from
users u
inner join
options o on o.user_id = u.id
group by 1, 2
having bool_and(o.option = 'access1')
;
id | name
----+-------
3 | bruce
答案 2 :(得分:0)
如果您想要只有access1的用户,我会使用聚合:
select user_id
from table2
group by user_id
having min(option) = max(option) and min(option) = 'access1';
答案 3 :(得分:0)
WITH users(id,name) AS ( VALUES
(1,'Donald'),
(2,'John'),
(3,'Bruce'),
(4,'Paul'),
(5,'Ronald'),
(6,'Steve')
), options(id,user_id,option) AS ( VALUES
(1,1,'access1'),
(2,1,'access2'),
(3,1,'access3'),
(4,2,'access1'),
(5,2,'access3'),
(6,3,'access1')
), user_access_count AS (
SELECT op.user_id,count(op.option) AS access_count
FROM options op
WHERE EXISTS(
SELECT 1 FROM options
WHERE option = 'access1'
)
GROUP BY op.user_id
)
SELECT u.id,u.name
FROM users u
INNER JOIN user_access_count uac ON uac.user_id = u.id
WHERE uac.access_count = 1;