Mysql: Отсортированный список дней рождений

49590031_88394

Выстраданное решение по отображению списка дней рождения на ближайшее несколько дней с нормальной сортировкой и переходом через новый год.

Основные проблемы, с которыми сталкивается желание вывести список дней рождения на портал:

  • Год рождения пользователя может быть не указан или указан неверно (особенно характерно для пользователей женского пола);
  • Проблема сортировки любых дат при переходе через год;

Рабочий запрос выглядит следующим образом:

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 |

Данное решение не претендует на уникальность и является далеко не единственным, однако оно работает и вполне может подойти для решения ваших задач.

Вы можете оставить комментарий ниже.