3

I have a table of subscription records for people subscribed to groups. There's a groupid column and a userid column (in addition to the primary key id). I want to find all the subscription rows of people subscribed to group 1 that do not also have a subscription record for group 2. I thought I could use an anti-join pattern, but I can't get it to work. I've tried:

SELECT
*
FROM subs s1
LEFT JOIN subs s2 ON s1.groupid=1 AND s2.groupid=2 AND s1.userid=s2.userid
WHERE s2.id IS NULL;

But that does not work (it returns subscription records with groupids that are not 1).

1 Answer 1

4

I would use group by for this:

select s.userid
from subs s
group by s.userid
having sum(case when s.groupid = 1 then 1 else 0 end) > 0 and
       sum(case when s.groupid = 2 then 1 else 0 end) = 0;

Each condition in the having clause counts records for one of the groups. The first condition says there is at least one row with groupid = 1. The second says there are no records with groupid = 2.

You can do what you want with a left join as well. Here is the approach:

SELECT s1.*
FROM subs s1 LEFT JOIN
     subs s2
     ON s1.userid = s2.userid AND s2.groupid = 2
WHERE  s1.groupid = 1 AND s2.id IS NULL;

Because it is a left join, the condition on the first table should go in the where clause.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.