Reputation: 5588
I want to select all of the unique Users where coach is true
and available is true
but if there are ANY Sessions for that user where call_ends_at is null
I don't want to include that user.
call_ends_at
can be NULL or have any number of various dates.
id:integer
name:string
coach: boolean
available: boolean
id:integer
coach_id: integer
call_ends_at:datetime
Here's what I tried:
SELECT DISTINCT "users".* FROM "users"
INNER JOIN "sessions" ON "sessions"."coach_id" = "users"."id"
WHERE "users"."coach" = true
AND "users"."available" = true
AND ("sessions"."call_ends_at" IS NOT NULL)
But this will still include users if there are sessions with non-null call_ends_at
columns.
Upvotes: 0
Views: 36
Reputation: 44250
-- I want to select all of the unique Users where coach is true and available is true
SELECT *
FROM users u
WHERE u.coach = true AND u.available = true
-- but if there are ANY Sessions for that user where call_ends_at is null
-- I don't want to include that user.
AND NOT EXISTS (
SELECT *
FROM sessions s
WHERE s.coach_id = u.id
AND s.call_ends_at IS NULL
) ;
Upvotes: 1
Reputation: 60472
This is possible with a single EXISTS:
SELECT u.*
FROM "users" u
WHERE u."coach" = true AND u."available" = true
AND EXISTS
(
SELECT s."coach_id"
FROM "sessions" s
WHERE s."coach_id" = u."id"
HAVING COUNT(*) = COUNT("call_ends_at") -- no NULLs
)
Depending on your actual data & indexes Gordon's answer might be more efficient.
Upvotes: 1
Reputation: 1270081
I think you can do what you want using EXISTS
and NOT EXISTS
:
SELECT u.*
FROM "users" u
WHERE u."coach" = true AND u."available" = true AND
EXISTS (SELECT 1
FROM "sessions" s
WHERE s."coach_id" = u."id"
)
NOT EXISTS (SELECT 1
FROM "sessions" s
WHERE s."coach_id" = u."id" AND
s."call_ends_at" IS NULL
);
Upvotes: 1