简体   繁体   中英

How do I exclude results if ANY associated row from a join table has NULL for a specific column?

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.

Users

id:integer
name:string
coach: boolean
available: boolean

Sessions

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.

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
                 );

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.

  -- 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
    ) ;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM