Будущий год рождения ошибка (SQL) - PullRequest
3 голосов
/ 23 июня 2011

это мой текущий SQL-запрос, который получает все предстоящие дни рождения моей компании в следующие 90 дней:

 SELECT
   user.birthday, user.name, MONTH(user.birthday)
   AS month, DAY(user.birthday) AS day
 FROM user WHERE
   (1 =
   (FLOOR(DATEDIFF(DATE_ADD(DATE(NOW()),INTERVAL
   90 DAY),birthday) / 365.25)) -
   (FLOOR(DATEDIFF(DATE(NOW()),birthday)
   / 365.25))) 
 ORDER BY MONTH(birthday),DAY(birthday)

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

Есть ли способ переупорядочить эти записи в одном и том же запросе SQL, чтобы сначала отображались текущие и будущие месяцы, а затем - месяцы следующего года?

Первое частичное решение благодаря Йохану

ORDER BY ( MONTH(birthday) > MONTH(NOW()             
        OR ((MONTH(birthday) = MONTH(now()) 
            AND DAY(birthday) >= DAY(NOW()) DESC
   , MONTH(birthday), DAY(birthday) 

Все же это требует небольшого улучшения. Если день рождения уже произошел, он должен отображаться ПОСЛЕ декабря в результатах. Пример того, что должно отображаться, если предположить, что это 27 июня

  • 28 июня: Джон Доу
  • 27 декабря: Мэри Райт
  • 5 июня (в следующем году, конечно): безумный максимум

Ответы [ 5 ]

1 голос
/ 23 июня 2011

Я думаю, что вы хотите знать, попадает ли день рождения каждого пользователя, перенесенный в текущий или следующий год, в ваш диапазон:

SELECT name, birthday
  FROM (SELECT name, birthday, YEAR(NOW()) - YEAR(birthday) AS years_ago
          FROM user) d
 WHERE DATE_ADD(birthday, INTERVAL years_ago YEAR)
           BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 90 DAY)
       OR
       DATE_ADD(birthday, INTERVAL (years_ago + 1) YEAR)
           BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 90 DAY);

(мне приходит в голову, что вы на самом деле хотите INTERVAL 3 MONTH, а не 90 DAY, особенно если вы собираетесь запускать этот запрос первого числа каждого месяца.)

1 голос
/ 23 июня 2011

Я не уверен, но кажется, что твой день рождения включает в себя год.Если это так, у вас будет диапазон дней рождения на пользователя (по одному на каждый год), и вы можете просто выбрать их в течение следующих 90 дней.день ваш запрос должен быть:

SELECT
  user.birthday
  , user.name
  , MONTH(user.birthday) AS month
  , DAY(user.birthday) AS day  
FROM user 
WHERE STR_TO_DATE(CONCAT(YEAR(NOW()),MONTH(birthday),DAY(birthday)),'%YYYY%M%D')
  BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 90 DAY) OR
STR_TO_DATE(CONCAT(YEAR(DATE_ADD(NOW(),INTERVAL 1 YEAR)),MONTH(birthday),DAY(birthday)),'%YYYY%M%D')
  BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 90 DAY) 
ORDER BY ( MONTH(birthday) > MONTH(NOW() 
           OR ((MONTH(birthday) = MONTH(now()) AND DAY(birthday) >= DAY(NOW()) DESC,
         MONTH(birthday), DAY(birthday)
1 голос
/ 23 июня 2011

Я считаю, что вам нужно заказать что-то, включающее год.

ORDER by date_format( date, "%d/%m/%Y" )

Я не эксперт, но что-то подобное тоже может сработать.

ORDER BY YEAR(birthday),MONTH(birthday),DAY(birthday)
0 голосов
/ 01 мая 2012

Я искал этот код, но не смог найти чистый / простой запрос (который также работает с високосными годами (проблема 29 февраля))

Итак, я сделал свойown.

Вот самый простой код для получения предстоящих дней рождения на следующие x дней (этот запрос также отображает дни рождения вчерашнего дня (или вы можете изменить его на число дней в прошлом)

SELECT name, date_of_birty 
FROM users 
WHERE DATE(CONCAT(YEAR(CURDATE()), RIGHT(date_of_birty, 6)))
        BETWEEN 
            DATE_SUB(CURDATE(), INTERVAL 1 DAY)
        AND
            DATE_ADD(CURDATE(), INTERVAL 5 DAY)
0 голосов
/ 23 июня 2011

Ваш запрос создаст полное сканирование таблицы.

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

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