I\'m trying to write a query to select users of a database whose birthdays are in the next 7 days.
I\'ve done a lot of research but I can\'t come up with a working s
So another approach you can take is to do a little more work before hitting the database layer. For example, I recently did this in a Laravel (PHP) and Postgres project. I basically built up an array of dates (ie. the next 7 days), and did a where in
query to find users with birthdays on those dates.
User::whereNotNull('birth_date')
->where('birth_date', '<=', $endDate)
->whereIn(DB::raw("to_char(birth_date, 'MMDD')"), Carbon::range($startDate, $endDate)->map(function ($date) {
return $date->format('md');
}))->get();
The accepted answer above from Lobo is flawed in that, if the query is run on December 31, and the user has a birthday on January 1, they will not be matched.
You must add logic to the query so that, if the birthday has already passed this year, you look at NEXT YEAR's birthday, not this year's. Details below:
SELECT *, IF( DAYOFYEAR( STR_TO_DATE(birthday, '%m/%d/%Y') ) < DAYOFYEAR( NOW() ),
DATE_ADD( STR_TO_DATE(birthday, '%m/%d/%Y'), INTERVAL YEAR( CURDATE() ) - YEAR( STR_TO_DATE(birthday, '%m/%d/%Y') ) + 1 YEAR ),
DATE_ADD( STR_TO_DATE(birthday, '%m/%d/%Y'), INTERVAL YEAR( CURDATE() ) - YEAR( STR_TO_DATE(birthday, '%m/%d/%Y') ) YEAR ) )
AS nextBirthday FROM persons
WHERE nextBirthday BETWEEN CURDATE() AND DATE_ADD( CURDATE(), INTERVAL 7 DAY);
We've had troubles with a calendar that had to show the next ten birthdays (including todays birthdays). I've reduced the solution I just found to the relevant parts:
SELECT first_name, last_name, birth_date,
IF (DAYOFYEAR(DATE_FORMAT(birth_date,'1980-%m-%d %T')) < DAYOFYEAR(DATE_FORMAT(NOW(),'1980-%m-%d %T')) ,
DAYOFYEAR(DATE_FORMAT(birth_date,'1980-%m-%d %T'))+368 ,
DAYOFYEAR(DATE_FORMAT(birth_date,'1980-%m-%d %T'))) AS upcomming
FROM users
WHERE birth_date IS NOT NULL AND birth_date !=0
ORDER BY upcomming ASC
LIMIT 0, 10
It sets every year (including the actual) to a leap year, so there won't be any problems with that. If you get close to the end of the year it's no problem, too. I'm quite statisfied to finally finding a working solution, so I wanted to share this, maybe it is of use for someone else :)
P.S.: If you don't want to show todays birthdays, just add a +1
after DAYOFYEAR(DATE_FORMAT(NOW(),'1980-%m-%d %T'))
This is what I did when I faced the same problem :
select * from users
where ( month(date_of_birth) > month(CURDATE())
and month(date_of_birth) < month(ADDDATE(CURDATE(),30)) )
or ( month(CURDATE()) = month(date_of_birth) and day(date_of_birth) >= day(CURDATE())
or month(ADDDATE(CURDATE(),30)) = month(date_of_birth) and day(date_of_birth) <= day(ADDDATE(CURDATE(),30)) )
or ( year(CURDATE()) > year(ADDDATE(CURDATE(),30)) and month(date_of_birth) < month(CURDATE()) and month(date_of_birth) > month(ADDDATE(CURDATE(),30)) )
Its very easy and simple. No need to use any if conditions or anything else you just need to use DATE_FORMAT() function of mysql.
Here is my sql query that is
SELECT id,email ,dob FROM `users` where DATE_FORMAT(dob, '%m-%d') >= DATE_FORMAT(NOW(), '%m-%d') and DATE_FORMAT(dob, '%m-%d') <= DATE_FORMAT((NOW() + INTERVAL +7 DAY), '%m-%d')