Given this schema in a Postgres database:
CREATE TABLE person (
id serial PRIMARY KEY,
name text,
birth_date date,
);
How would I query the table to get the date of each person's next birthday after today?
For example if Bob's birth_date
is 2000-06-01 then his next birthday would be 2016-06-01.
Note: I'm not looking for the birth_date
+ a pre-defined interval
but rather the next anniversary of a person's birth.
I've written the equivalent in Python:
def next_birthday(self):
today = datetime.date.today()
next_birthday = self.birth_date.replace(year=today.year)
if next_birthday < today:
next_birthday = next_birthday.replace(year=today.year + 1)
return next_birthday
However I'd like to see if Postgres can do this in a more performant way.
select birth_date,
cast(birth_date + ((extract(year from age(birth_date)) + 1) * interval '1' year) as date) as next_birthday
from person
where name = 'Bob'
The expression (extract(year from age(birth_date)) + 1) * interval '1' year
calculates the age at the next birthday in (complete) years. When adding that to the date of birth, this gives the next birthday.
The cast is necessary to get a real date
back, because date + interval
returns a timestamp (including a time).
If you remove the where
condition, you'll get all "next" birthdays.
You can also get a list of the upcoming birthdays in e.g. the next 30 days using something like this:
select next_birthday,
next_birthday - current_date as days_until_next
from (
select birth_date,
cast(birth_date + ((extract(year from age(birth_date)) + 1) * interval '1' year) as date) as next_birthday
from person
) as upcoming
where upcoming.next_birthday <= current_date + 30
order by next_birthday;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With