Как выбрать всех пользователей, у которых день рождения в определенный период, без учета года?

Нагуглил в интернете сотню решений, но у всех есть какие-то нюансы работы.
Основная проблема в том, что мне нужно выбрать всех пользователей, у которых дни рождения в указанный период без учета года.
Например, выбрать всех, у кого ДР между 10 января и 25 января и не важно какой год рождения.
Пытался остановиться на чем-то подобном, но работает все равно не верно.
SELECT `ID` FROM `users` WHERE DATE_FORMAT(`BIRTHDAY`,'%d.%m') BETWEEN '01.01' AND '19.01'
Выбирает пользователей с ДР:
01.01
05.01
16.01
А при таком условии BETWEEN '01.02' AND '15.01'
05.01 и 16.01 все равно остаются.

Подскажите, пожалуйста, как сделать это правильно?
  • Вопрос задан
  • 5452 просмотра
Решения вопроса 1
blo
@blo
инженер-программист
Может так? Т.е. формат не DDMM a MMDD. Но при диапазоне с переходом через границу года будут проблемы.
SELECT `ID` FROM `users` WHERE DATE_FORMAT(`BIRTHDAY`,'%c%d') BETWEEN '101' AND '119'
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
savostin
@savostin
Еще один программист
Может DAYOFYEAR использовать?
SELECT `ID` FROM `users` WHERE DAYOFYEAR (`BIRTHDAY`) BETWEEN DAYOFYEAR ('01.01.1900') AND DAYOFYEAR ('19.01.1900')
Ответ написан
AxisPod
@AxisPod
Я бы вообще посоветовал так не делать, приведенный вами запрос не должен работать с индексом, т.к. вы запросили DATE_FORMAT для данных, что приведет к обработке всех выражений, сделайте отдельное поле, в которое и кидайте данные как вам надо, для заполнения можно триггер использовать, а по нему уже искать.
Ответ написан
Комментировать
subvillion
@subvillion
Выборка происходит полная, но тут применяется «реформат» даты, что при больших объемах приведет к снижению производительности.

Я бы поступил «классически», выборка с учетом года от 1900 до ~3000 + нет проблемы с границами.
Ответ написан
javax
@javax
Software Architect, Java Developer since 1996
Сделайте колонку с порядковым номером дня в году для дня рождения. Тогда сможете индекс сделать и условие простое будет. Ну только, как указали выше, отдельно учесть переход через границу года
Ответ написан
Комментировать
Сталкивался с похожим…
Проблема была только в том, что некоторые записи имеют год а некоторые нет.
Выбираем только месяц+день и ставим год теперешний. Эту переменную ставим индексом и фильтруем как хотим.
От селектов DATE_FORMAT отказался так как база очень больших размеров, и выборка по int индексу в разы быстрее.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы