MySQL-Query: Howto select upcoming birthdays

In a recent software project I needed to select the upcoming birthdays of the
users. But now I detected a problem with the turn of the year. After some time
of researching and trying, I found a stable solution. For your convenience,
here’s the code:
SET @today = '2007-12-20';
SELECT
user_id,
birthday,
DATE_FORMAT(@today, '%Y') - DATE_FORMAT(birthday, '%Y') + IF(
DATE_FORMAT(birthday, '%m%d') < DATE_FORMAT(@today, '%m%d'), 1, 0) AS new_age,
DATEDIFF(birthday + INTERVAL YEAR(@today) - YEAR(birthday) +
IF(DATE_FORMAT(@today, '%m%d') > DATE_FORMAT(birthday, '%m%d'), 1, 0) YEAR,
@today) AS days_to_birthday
FROM users
HAVING days_to_birthday < 14
ORDER BY days_to_birthday ASC;

And you can easily extend it to limit the result to some specific ages. This is
very useful if you want only the big O coming up:
...
HAVING days_to_birthday < 14 AND new_age IN (10,20,30,40,50,60,70,80,90,100)
...


12 Responses to “MySQL-Query: Howto select upcoming birthdays”

  • Daniel Sturm Says:

    Hey, thanx for your post! Saved my day ;)

  • jamal Says:

    hey, you rock. I used your code and it’s working fantastic.

  • Mario Says:

    Another saved day! thank you!

  • Patrick Says:

    This is great, worked like a charm.
    Although I found one little problem if the birthdate is next year.

    Ex. Today is Nov 25 and the birthdate is Jan 4, the new_age is short by 1. I’ll try fixing this on my own and hopefully I remember to post it here. Anyway, thanks!

  • Patrick Says:

    ~Here’s the fix I was talking about~

    For the line that says:

    DATE_FORMAT(@today, ‘%Y’) – DATE_FORMAT(birthday, ‘%Y’) + IF(
    DATE_FORMAT(birthday, “%m%d”) < DATE_FORMAT(@today, "%m%d"), 1, 0) AS new_age,

    I just replaced 0 with:

    IF(DATE_FORMAT(birthday, "%m%d") = DATE_FORMAT(@today, "%m%d"), 0, 1)

  • Tobias Says:

    Thanks for your reply. But the statement as posted on the top is correct. Try it again with the following dates, and you should get the same results like me (supposed today is 2011-11-25):

    || *user_id* || *birthday* || *new_age* || *days_to_birthday* ||
    || 1 || 2000-01-04 || 12 || 40 ||
    || 2 || 2000-11-24 || 12 || 365 ||
    || 3 || 2000-11-25 || 11 || 0 ||
    || 4 || 2000-11-26 || 11 || 1 ||

    • #2 (who has had birthday yesterday) has to wait 365 more days. That means the leap year is taken into consideration: 2012-11-25 is 366 days from today.
    • #3 Happy birthday to you: you are getting 11 years old today.
    • #4 can celebrate his 11th birthday tomorrow.
    • #1 has to wait 40 more days until his 12th birthday.
  • Patrick Says:

    Yes, thanks for that but if you look at your person #1, his birthday is 2000-01-04 and is 12 years old on 2011-11-25.

    After 40 days however, he should be 13 years old (new_age).

    The same is true for your person #2.

    After 365 days, his “new_age” should be 13.

  • Patrick Says:

    Know what, sorry about the last comment. Obviously I’m not 100% awake.

    You are correct, the “new_age” for both #1 and #2 should be 12.

    I’ll try this out tonight when I get back home from work because I’m a little busy at the moment. I’ll let you know what I find out.

    Thanks!

  • Patrick Says:

    I see now why we are having different results.

    Your query has instead. Yours is definitely better and more efficient.

    Sorry for making a scene.

    Thanks for your help though! :)

  • Patrick Says:

    Your query for the new_age has “>” (greater than) instead. Yours is definitely better and more efficient.

  • smronju Says:

    Thanks you saved my day :)

Leave a Reply