tags:

views:

53

answers:

3

A user can have suspensions. I want to select a user and his suspensions, but I only want the suspensions where the suspensions.suspended_date > now(). I want to return the user regardless.

It sounds like a left join, but:

SELECT *
FROM users
LEFT JOIN suspensions ON suspensions.user_id=users.id
WHERE suspensions.suspended_date > now()

Would work fine if they DO have suspensions, but would cause trouble if they don't have any, because the where clause would always fail.

How can I write this with one query?

A: 
SELECT *
FROM users
LEFT JOIN suspensions ON suspensions.user_id=users.id
WHERE suspensions.suspended_date > now() or suspensions.suspended_date is null

That should do it.

Jon
This won't work because an absent suspension isn't "null"..it's just nonexistant.
ryeguy
When a left join doesn't match null will show up for the columns that are in the table that didn't match the join clause.
Jon
Hmm..it doesn't in Postgres. Which DB does that work for you in?
ryeguy
That's interesting. Did you try my query in Postgres? I looked up the documentation and my syntax looks like it works there too. It works in tSQL and MySQL (as I recall).
Jon
Yeah, I tried it in postgres, copied and pasted. I didn't get a result. I mean of course a left join fills the nonexistant right table with nulls, but it looks like it doesn't treat unmatched right rows as nulls until after the query is done. Odd.
ryeguy
+3  A: 

you could try moving the filter from the WHERE to the JOIN statement

SELECT *
FROM   users 
       LEFT JOIN suspensions 
       ON suspensions.user_id=users.id AND suspensions.suspended_date > now()
Scott Ivey
A: 

would this work?

SELECT *
FROM users
LEFT JOIN suspensions ON suspensions.user_id=users.id
WHERE suspensions.suspended_date > now() or suspensions.user is null
Mateusz Kubiczek