Sql 如何在没有选择的情况下进行左连接

Sql 如何在没有选择的情况下进行左连接,sql,Sql,我有两个表,“user”和“user\u things”。我想让所有用户都拥有一个或多个内容,但我不想检索内容本身(我只希望每个用户返回一行) 示例:我想找到所有拥有“帽子”和“汽车”的用户。如果有两个用户有此项,我只希望返回两行(不是4行)。选择另一个表中存在“car”和“hat”记录的所有用户 select * from User u where exists ( select 'x' from Things t where t.userid = u.

我有两个表,“user”和“user\u things”。我想让所有用户都拥有一个或多个内容,但我不想检索内容本身(我只希望每个用户返回一行)


示例:我想找到所有拥有“帽子”和“汽车”的用户。如果有两个用户有此项,我只希望返回两行(不是4行)。

选择另一个表中存在“car”和“hat”记录的所有用户

select
  *
from
  User u
where
  exists (
    select 'x' 
    from Things t 
    where t.userid = u.id and t.thingname = 'hat') and
  exists (
    select 'x' 
    from Things t 
    where t.userid = u.id and t.thingname = 'car')
或者,你也可以这样做,尽管我认为这不太好,语义不太正确:

select distinct
  u.*
from
  Users u
  inner join Things tc on tc.userid = u.id and tc.thingname = 'car'
  inner join Things th on th.userid = u.id and th.thingname = 'hat'
甚至:

select
  u.*
from
  Users u
where
  (select 
    count('x') 
  from Things t
  where t.userid = u.id and t.thingname in ('car', 'hat')) = 2

虽然最后一个也可能返回没有汽车和两顶帽子的用户

选择其他表中存在“car”和“hat”记录的所有用户

select
  *
from
  User u
where
  exists (
    select 'x' 
    from Things t 
    where t.userid = u.id and t.thingname = 'hat') and
  exists (
    select 'x' 
    from Things t 
    where t.userid = u.id and t.thingname = 'car')
或者,你也可以这样做,尽管我认为这不太好,语义不太正确:

select distinct
  u.*
from
  Users u
  inner join Things tc on tc.userid = u.id and tc.thingname = 'car'
  inner join Things th on th.userid = u.id and th.thingname = 'hat'
甚至:

select
  u.*
from
  Users u
where
  (select 
    count('x') 
  from Things t
  where t.userid = u.id and t.thingname in ('car', 'hat')) = 2
虽然最后一个也可能返回没有汽车和两顶帽子的用户

使用聚合:

select u.userid, u.username
from user u join
     user_things ut
     on ut.userid = u.id
group by t1.userid, t1.username
having sum(case when ut.thingname = 'hat' then 1 else 0 end) > 0 and
       sum(case when ut.thingname = 'car' then 1 else 0 end) > 0 
having
子句的第一部分计算“hat”的数量。第二个计算“汽车”的数量。
条件要求两者都存在。

使用聚合:

select u.userid, u.username
from user u join
     user_things ut
     on ut.userid = u.id
group by t1.userid, t1.username
having sum(case when ut.thingname = 'hat' then 1 else 0 end) > 0 and
       sum(case when ut.thingname = 'car' then 1 else 0 end) > 0 
having
子句的第一部分计算“hat”的数量。第二个计算“汽车”的数量。
条件要求两者都存在。

更简单的解决方案是

select user.id, user.name
  from user
 inner join things t on t.userid = user.id
 where t.thingname in ('car', 'hat')
 group by user.id, user.name
having count(*) >= 2; -- (2 for 'car' and 'hat', 3 for 'car', 'hat' and 'bike', ...)
一个更简单的解决方案是

select user.id, user.name
  from user
 inner join things t on t.userid = user.id
 where t.thingname in ('car', 'hat')
 group by user.id, user.name
having count(*) >= 2; -- (2 for 'car' and 'hat', 3 for 'car', 'hat' and 'bike', ...)

Use EXISTS(两次),如下所示:Use EXISTS(两次),如下所示: