Reputation: 5173
Suppose I have a Client with many Payments. How do I query to get all clients that have no payment records in the last 90 days?
clients
=======
id integer
name string
payments
========
id integer
client_id integer
created_at datetime
Essentially the inverse of:
select *
from clients
inner join payments on payments.client_id = clients.id
where payments.created_at > utc_timestamp() - interval 90 day
Hopefully more efficient than:
select *
from clients
where id not in (
select *
from clients
inner join payments on payments.client_id = clients.id
where payments.created_at > utc_timestamp() - interval 90 day
)
Upvotes: 1
Views: 1456
Reputation: 238076
Ensure there's an index on payments(client_id)
, or even better, payments(client_id, created_at
).
For alternative way to write your query, you could try a not exists
, like:
select *
from clients c
where not exists
(
select *
from payments p
where p.payments.client_id = clients.id
and payments.created_at > utc_timestamp() - interval 90 day
)
Or an exclusive left join:
select *
from clients c
left join
payments p
on p.payments.client_id = clients.id
and payments.created_at > utc_timestamp() - interval 90 day
where p.client_id is null
If both are slow, add the explain extended
output to your question, so we can see why.
Upvotes: 1
Reputation: 37388
select *
from clients
left join payments on
payments.client_id = clients.id and
payments.created_at > utc_timestamp() - interval 90 day
where payments.client_id is null
Upvotes: 0