Написал очередной костыль, для решения тривиальной задачи — вывод дней рождения на корпоративном портале.
Качество существующего кода оказалось отвратительным, и как показал поиск в интернете — нормальных решений также нет. Основная проблема это переход через новый год.
Казалось бы ничего сложного в запросе нет — обыкновенный «BETWEEN», на самом деле это не так, а почему я объясню ниже.
Решение в лоб: мы не должны учитывать год, при выборке, т.е. простейшим «WHERE»/»BETWEEN». Данный запрос будет верен, до нового года. После нового года пойдет 01 месяц (январь), который по правилам сортировки будет выше нашей выборки.
WHERE (date_format(now()+interval 7 day,'%m-%d')<date_format(bday,'%m-%d') AND date_format(NOW(),'%m-%d')<=date_format(bday,'%m-%d')) |
Для решения данной проблемы, мы добавим в выборку год. Год должен быть одинаковым у всех дат, в моем случае 0000, при этом, если месяц не будет совпадать с выбираем, то мы добавим к этому году единицу, т.е. получим 0001. Данная дата уже поддается нормально сортировки. Итоговый запрос и листинг вывода, можно видеть ниже.
SELECT id,name,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 mlt_edata 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; |
+-----+--------------------+------------+-------+------------+ | id | name | bday | bday1 | date1 | +-----+--------------------+------------+-------+------------+ | 293 | Наталья | 2013-12-27 | 12-27 | 0000-12-27 | | 700 | Дарья | 2013-12-27 | 12-27 | 0000-12-27 | | 725 | Юлия | 2013-12-28 | 12-28 | 0000-12-28 | | 443 | Наталья | 2013-12-28 | 12-28 | 0000-12-28 | | 403 | Анна | 2013-12-28 | 12-28 | 0000-12-28 | | 482 | Евгения | 1981-12-30 | 12-30 | 0000-12-30 | | 18 | Оксана | 2013-01-01 | 01-01 | 0001-01-01 | | 270 | Евгений | 2013-01-01 | 01-01 | 0001-01-01 | | 168 | Алина | 2013-01-01 | 01-01 | 0001-01-01 | | 92 | Елена | 2013-01-01 | 01-01 | 0001-01-01 | | 90 | Ирина | 2013-01-01 | 01-01 | 0001-01-01 | | 87 | Варвара | 2013-01-01 | 01-01 | 0001-01-01 | | 86 | Татьяна | 2013-01-01 | 01-01 | 0001-01-01 | | 71 | Анастасия | 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 | | 642 | Любовь | 2013-01-08 | 01-08 | 0001-01-08 | | 607 | Татьяна | 2013-01-09 | 01-09 | 0001-01-09 | | 617 | Елена | 2013-01-09 | 01-09 | 0001-01-09 | +-----+--------------------+------------+-------+------------+ 21 rows in set (0.00 sec) |