SQL, который перечисляет все дни рождения в течение следующих и предыдущих 14 дней - PullRequest
4 голосов
/ 09 июня 2009

У меня есть таблица MySQL member с полем DOB, в котором хранятся даты рождения всех участников в формате DATE (обратите внимание: в нем есть часть "Год")

Я пытаюсь найти правильный SQL для:

  • Список всех дней рождения в течение следующих 14 дней

и другой запрос к:

  • Список всех дней рождения за предыдущие 14 дней

Непосредственное сравнение текущей даты по:

(DATEDIFF(DOB, now()) <= 14 and DATEDIFF(DOB, now()) >= 0)

ничего не получит, поскольку текущий год и год DOB разные.

Однако преобразование DOB в «этот год» не будет работать вообще, потому что сегодня может быть 1 января, а кандидат может получить DOB 31 декабря (или наоборот)

Было бы здорово, если бы вы могли помочь, большое спасибо! :)

Ответы [ 6 ]

3 голосов
/ 02 мая 2012

Вот самый простой код для получения следующих дней рождения на следующие x дней и предыдущие x дней

этот запрос также не подвержен високосным годам

SELECT name, date_of_birty 
FROM users 
WHERE DATE(CONCAT(YEAR(CURDATE()), RIGHT(date_of_birty, 6)))
          BETWEEN 
              DATE_SUB(CURDATE(), INTERVAL 14 DAY)
          AND
              DATE_ADD(CURDATE(), INTERVAL 14 DAY)
2 голосов
/ 24 июля 2012

@ У Эли был хороший ответ, но жесткое кодирование 351 делает его немного запутанным и сбрасывается на 1 в високосные годы.

Проверяет, наступит ли день рождения (доб) в течение следующих 14 дней. Первая проверка, если в том же году. Вторая проверка - если, скажем, 27 декабря, вы также захотите включить даты января.

При DAYOFYEAR( CONCAT(YEAR(NOW()),'-12-31') ) мы решаем, использовать ли 365 или 366 на основе текущего года (для високосного года).

SELECT dob
FROM birthdays
WHERE DAYOFYEAR(dob) - DAYOFYEAR(NOW()) BETWEEN 0 AND 14 
OR 
DAYOFYEAR( CONCAT(YEAR(NOW()),'-12-31') ) - ( DAYOFYEAR(NOW()) - DAYOFYEAR(dob) ) BETWEEN 0 AND 14 
1 голос
/ 09 июня 2009

Моя первая мысль была о том, что было бы легко просто использовать DAYOFYEAR и принять разницу, но это фактически становится своего рода трюком в начале / конце года. Тем не менее:

WHERE 
DAYOFYEAR(NOW()) - DAYOFYEAR(dob) BETWEEN 0 AND 14 
OR DAYOFYEAR(dob) - DAYOFYEAR(NOW())  > 351

Должно работать, в зависимости от того, насколько вы заботитесь о високосных годах. «Лучшим» ответом, вероятно, было бы извлечь DAY () и MONTH () из dob и использовать MAKEDATE (), чтобы построить дату в текущем (или потенциальном прошлом / следующем) году и сравнить с ней.

1 голос
/ 09 июня 2009

Легко,

Мы можем получить ближайший день рождения (т.е. день рождения в этом году) по этому коду:

dateadd(year,datediff(year,dob,getdate()),DOB)

используйте это в своих сравнениях! это будет работать.

0 голосов
/ 21 января 2013

Это мой запрос за 30 дней до проверки:

select id from users where 
((TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d')))-TO_DAYS(NOW()))>=-30 
AND (TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d')))-TO_DAYS(NOW()))<=0)
OR (TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d')))-TO_DAYS(NOW()))>=(365-31)

и 30 дней после:

select id from users where 
((TO_DAYS(NOW())-TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d'))))>=-31 
AND (TO_DAYS(NOW())-TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d'))))<=0)
OR (TO_DAYS(NOW())-TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d'))))>=(365-30)
0 голосов
/ 09 июня 2009

Существует несколько вариантов, я сначала попытался бы преобразовать их по количеству лет между текущим годом и годом строки (т.е. добавить их возраст).

Другим вариантом является номер дня в году (но вам все равно придется беспокоиться об арифметике при переворачивании или по модулю).

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