Reputation:
I have two tables, "user", and "user_things". I want to get all users with one or more things, but I don't want to retrieve the things themselves (I only want one row per user returned).
Table 1:
id
username
Table 2:
id
userid
thingname
Example: I want to find all users with a "hat" and a "car". If there are two users with this, I want only two rows returned (not 4).
Upvotes: 1
Views: 4486
Reputation: 15319
A simpler solution is
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', ...)
Upvotes: 1
Reputation: 1270513
Use aggregation:
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
The first part of the having
clause counts the number of "hat"s. The second counts the number of "car"s. The >
condition requires that both are present.
Upvotes: 1
Reputation: 116140
Select all users for which a record for 'car' and for 'hat' exists
in the other table.
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')
Alternatively, you can do this, although I think it's less nice, less semantically correct:
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'
Or even:
select
u.*
from
Users u
where
(select
count('x')
from Things t
where t.userid = u.id and t.thingname in ('car', 'hat')) = 2
Although the last one might also return users that have no car and two hats.
Upvotes: 0