Reputation: 11882
How do I find all the user records created exactly multiple whole months/quarters ago in Postgres SQL? Is it possible?
In Postgres, you can find a date which is exactly 1 month away from a datetime field, like:
select created_at + interval '1 month' from users limit 1;
?column?
----------------------------
2016-10-05 17:05:14.811537
(1 row)
If today is 9/27/2016, I want to find all the user records created on 8/27/2016, 7/27/2016, 6/27/2016, ... 1/27/2015, etc, etc. How do I do this in SQL?
Note this isn't simply a comparison of date due to the fact that some months have 31 days while others have 28, 29, 30 days.
If today is 2/28/2015 (non-leap year), I want all the users created on the following dates: 1/28/2015, 1/29/2015, 1/30/2015, 1/31/2015, 12/28/2014, 12/29/2014, 12/30/2014, 12/31/2014, etc etc.
If today is 2/28/2016 (leap year), I want all the users created on the following dates: 1/28/2015, 12/28/2014, 11/28/2014, etc etc. (But not on 1/29/2015, 1/30/2015, 1/31/2015, as those users will be picked up the next day, see below).
If today is 2/29/2016 (leap year), I want all the users created on the following dates: 1/29/2015, 1/30/2015, 1/31/2015, 12/29/2014, 12/30/2014, 12/31/2014, etc etc.
If today is 3/31/2016, I want all the users created on 12/31/2015, 1/31/2016, but not anyone created in February 2016 because they would have been picked on previous days of March 2016.
How do I do the above with quarters instead of months?
Another question related to this is performance. If I create an index on created_at
, would a whole table scan be avoided if I do this type of queries?
Thank you.
Upvotes: 1
Views: 141
Reputation: 2162
Well... If You think of it, You want to compare day number in reality, right? So You should do just that:
select
*
from
users
where
date_part('day', created_at) = date_part('day', current_timestamp)
OR
(
-- Check if this is the last day of month
extract(month from current_timestamp + '1day'::interval) <> extract(month from current_timestamp)
AND
date_part('day', created_at) > date_part('day', current_timestamp)
)
limit
1
;
And regarding Your index question - yes.
Inspiration for checking last day of a month taken from here.
Basically, if I still do not get Your requirement, You should be able to easily modify my code to meet it, if You understand it. :)
Upvotes: 1