My table looks like
ID | PersonName | Birthday | IntDate
--------------------------------------
1 | Joe | 1977-08-20 | 820
2 | Sandy | 1985-02-27 | 227
3 | Jane | 1981-11-01 | 1101
The INDEXed helper column IntDate is just an int = month*100+days, written at insert/update and used to speed up queries for all birthdays in a given date range (e.g. between [1001;1031] for October) independent of the year. (So I don't have to filter based on EXTRACT or DATE_PART functions for day and month in the WHERE clause, as the birthday DATE includes a year in the past.)
Given a certain date (e.g. 2025-05-01), I want to query the next birthday date of the persons and the upcoming anniversary (what birthday is coming).
Then I want to sort the list by the next birthday date (this or next year).
For 2025-05-01, the list might look like:
ID | PersonName | Birthday | NextBirthday ^ | Anniversary (at upcoming birthday)
-----------------------------------------------------------
1 | Joe | 1977-08-20 | 2025-08-20 | 48
3 | Jane | 1981-11-01 | 2025-11-01 | 44
2 | Sandy | 1985-02-27 | 2026-02-27 | 41
Is that possible using an SQL SELECT query in PostgreSQL?
You use helper column (IntDate) for search and index.
You can use this value to detect next anniversary year. Calculate those value for given date '2025-05-01' -> '501' and compare with IntDate. If greater then next birth day is in next year.
See example. (cross joins only for simplicity of calculation)
select *
,birthday+ (cAge+case when idt>intdate then +1 else 0 end)* interval '1 year' nextBirthDay
,cAge+case when idt>intdate then +1 else 0 end Anniversary
from test
cross join ( values('2025-05-01'::date)) t(cDt) -- parameter
cross join lateral ( values(extract(month from cdt)*100+extract(day from cdt)
,(extract (year from cdt)-extract(year from birthday))::int
) ) c(iDt,cAge) -- precalculations
| id | personname | birthday | intdate | cdt | idt | cage | nextbirthday | anniversary |
|---|---|---|---|---|---|---|---|---|
| 1 | Joe | 1977-08-20 | 820 | 2025-05-01 | 501 | 48 | 2025-08-20 00:00:00 | 48 |
| 2 | Sandy | 1985-02-27 | 227 | 2025-05-01 | 501 | 40 | 2026-02-27 00:00:00 | 41 |
| 3 | Jane | 1981-11-01 | 1101 | 2025-05-01 | 501 | 44 | 2025-11-01 00:00:00 | 44 |
| 4 | Mike | 2000-05-01 | 501 | 2025-05-01 | 501 | 25 | 2025-05-01 00:00:00 | 25 |