Выстраданное решение по отображению списка дней рождения на ближайшее несколько дней с нормальной сортировкой и переходом через новый год.
Основные проблемы, с которыми сталкивается желание вывести список дней рождения на портал:
- Год рождения пользователя может быть не указан или указан неверно (особенно характерно для пользователей женского пола);
- Проблема сортировки любых дат при переходе через год;
Рабочий запрос выглядит следующим образом:
SELECT id,name,mname,bday, date_format(bday,'%m-%d') as bday1, DATE_ADD(bday, INTERVAL-YEAR(bday)+(DATE_FORMAT(CURRENT_DATE, '%m') > DATE_FORMAT(bday, '%m')) year) as date1 FROM user_data WHERE DATE_ADD(bday, INTERVAL-YEAR(bday)+(DATE_FORMAT(CURRENT_DATE, '%m') > DATE_FORMAT(bday, '%m')) year) BETWEEN DATE_ADD(CURRENT_DATE, INTERVAL -YEAR(CURRENT_DATE) YEAR ) AND DATE_ADD(DATE_ADD(CURRENT_DATE, INTERVAL 15 DAY), INTERVAL -YEAR(CURRENT_DATE) YEAR ) ORDER BY date1 ASC LIMIT 15; |
+-----+--------------------+----------------------+------------+-------+------------+ | id | name | mname | bday | bday1 | date1 | +-----+--------------------+----------------------+------------+-------+------------+ | 330 | Виталий | | 2013-03-30 | 03-30 | 0000-03-30 | | 92 | Елена | | 2013-03-31 | 03-31 | 0000-03-31 | | 696 | Олег | | 2013-03-31 | 03-31 | 0000-03-31 | | 279 | Михаил | | 2013-03-31 | 03-31 | 0000-03-31 | | 703 | Юлия | | 2013-03-31 | 03-31 | 0000-03-31 | | 227 | Олеся | | 2013-04-03 | 04-03 | 0000-04-03 | | 417 | Екатерина | | 2013-04-03 | 04-03 | 0000-04-03 | | 737 | Екатерина | | 2013-04-03 | 04-03 | 0000-04-03 | | 45 | Елена | | 2013-04-04 | 04-04 | 0000-04-04 | | 329 | Ольга | | 2013-04-04 | 04-04 | 0000-04-04 | | 373 | Алексей | | 2013-04-04 | 04-04 | 0000-04-04 | | 460 | Мария | | 2013-04-04 | 04-04 | 0000-04-04 | | 271 | Наталья | | 2013-04-07 | 04-07 | 0000-04-07 | | 351 | Анна | | 2013-04-09 | 04-09 | 0000-04-09 | | 274 | Елена | | 2013-04-11 | 04-11 | 0000-04-11 | +-----+--------------------+----------------------+------------+-------+------------+ 15 rows in set (0.00 sec) |
Сначала нам надо избавиться от года.
Вычесть текущий мы не можем, по этому определяем год в поле дня рождения (bday) и вычитаем его:
DATE_ADD(bday, INTERVAL-YEAR(bday)... |
Записываем поле как «date1»:
+-----+----------------------+----------------------------+------------+-------+------------+ | id | name | mname | bday | bday1 | date1 | +-----+----------------------+----------------------------+------------+-------+------------+ | 791 | Анна | | 2013-03-02 | 03-02 | 0000-03-02 | | 730 | Ирина | | 2013-03-03 | 03-03 | 0000-03-03 | | 736 | Татьяна | | 2013-03-04 | 03-04 | 0000-03-04 | | 799 | Дмитрий | | 2013-03-04 | 03-04 | 0000-03-04 | | 179 | Анна | | 2013-03-06 | 03-06 | 0000-03-06 | | 792 | Анна | | 2013-03-06 | 03-06 | 0000-03-06 | | 221 | Евгения | | 2013-03-07 | 03-07 | 0000-03-07 | |
Далее решаем вопрос с переходом через год.
Для этого каждому пользователю с днем рождения в месяце, который меньше текущего, мы добавляем год:
DATE_ADD(bday, INTERVAL-YEAR(bday)+(DATE_FORMAT(CURRENT_DATE, '%m') > DATE_FORMAT(bday, '%m')) year) as date1 |
| 763 | Дарина | | 2013-12-28 | 12-28 | 0000-12-28 | | 403 | Анна | | 2013-12-28 | 12-28 | 0000-12-28 | | 443 | Наталья | | 2013-12-28 | 12-28 | 0000-12-28 | | 482 | Евгения | | 2013-12-30 | 12-30 | 0000-12-30 | | 87 | Варвара | | 2013-01-01 | 01-01 | 0001-01-01 | | 766 | Тимур | | 2013-01-01 | 01-01 | 0001-01-01 | | 786 | Юлия | | 2013-01-01 | 01-01 | 0001-01-01 | | 36 | Елена | | 2013-01-04 | 01-04 | 0001-01-04 | | 742 | Илья | | 2013-01-05 | 01-05 | 0001-01-05 | | 570 | Антон | | 2013-01-06 | 01-06 | 0001-01-06 | | 550 | Ксения | | 2013-01-07 | 01-07 | 0001-01-07 | |
Данное решение не претендует на уникальность и является далеко не единственным, однако оно работает и вполне может подойти для решения ваших задач.