Postgres/SQL - 查找仅在与另一个表连接时只有一个匹配记录的记录

3
假设我有两个表,其中一个表代表拥有多只狗的用户:
用户表
id name
1 aaaa 2 bbbb 3 cccc 4 dddd
狗表
id user_id breed
1 1 poodle 2 1 lab 3 2 lab 4 3 bulldog 5 4 lab 6 4 lab
我想找到只拥有一只且仅有一只“lab”品种狗的用户。
期望得到以下结果:
用户表
id name
2 bbbb
在这种情况下,只有狗id为3的狗符合要求,因为它的主人只有一只狗,而且是一只拉布拉多。 SELECT users.* FROM users INNER JOIN dogs ON users.id = dogs.user_id WHERE dogs.breed = 'lab' 从这里开始怎么做?我觉得我可能忽略了一些显而易见的东西,这可能是一个常见的需求,但是我的谷歌搜索技巧此时正在失败。寻求面向Postgres的解决方案,但欢迎任何帮助!
2个回答

3
模式和插入语句:
create table USERS (id int, name varchar(20));
 insert into  USERS values(1    ,'aaaa');
 insert into  USERS values(2    ,'bbbb');
 insert into  USERS values(3    ,'cccc');
 insert into  USERS values(4    ,'dddd');

 create table DOGS(id int,  user_id int, breed varchar(20));
 insert into DOGS values(1  ,1  ,'poodle');
 insert into DOGS values(2  ,1  ,'lab');
 insert into DOGS values(3  ,2  ,'lab');
 insert into DOGS values(4  ,3  ,'bulldog');
 insert into DOGS values(5  ,4  ,'lab');
 insert into DOGS values(6  ,4  ,'lab');
 

查询:
  SELECT u.id,u.name FROM USERS u
     INNER JOIN DOGS d
     ON u.id = d.user_id 
     WHERE d.breed = 'lab'
     and exists (
                select 1 from DOGS where DOGS.user_id=d.user_id 
                group by user_id having count(*)=1
                );

输出:

     |id | name|
     |---|-----|
     | 2 | bbbb|

db<fiddle here

的英译中为:

在此处查看 db<fiddle here


1
一种方法是使用带有 having 子句的聚合:
select u.id, u.name
from users u join
     dogs d
     on d.user_id = u.id
group by u.id, u.name
having count(*) = 1 and        -- one dog
       min(d.breed) = 'lab';   -- it's a lab

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接