SQL即将到来的生日问题

时间:2014-02-18 20:57:49

标签: mysql sql

任何人都可以修复以下SQL代码,这些代码即将到来的生日:

SELECT *
FROM personal
WHERE 1 = ( FLOOR( DATEDIFF( DATE_ADD( DATE( NOW( ) ) , INTERVAL :interval DAY ) , dob ) / 365.25 ) ) -
      ( FLOOR( DATEDIFF( DATE_ADD( DATE( NOW( ) ) , INTERVAL -1 DAY ) , dob ) / 365.25 ) )
ORDER BY MONTH( dob ), DAY( dob )
LIMIT :rangeStart,:limit

除此之外,如果年份结束,则会出现订单错误。例如。你在12月提前1个月检查,然后1月生日将在12月之前订购。 我在这里看到了一些关于这样做的帖子,但是他们似乎都没有得到这个部分的正确性。我尝试使用以下ORDER BY子句,来自另一篇文章,这似乎适用于其他人,但是当我运行它时,我得到语法错误:

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

2 个答案:

答案 0 :(得分:0)

更新了答案...

想到一个更清洁的方法来实现这个目标:

SELECT *
  FROM (
  SELECT *
      ,DATE_ADD( MAKEDATE( YEAR( NOW() ), DAYOFYEAR( dob ) )
                ,INTERVAL IF( DAYOFYEAR( dob ) < DAYOFYEAR( NOW() ), 1, 0 ) YEAR
               )
       AS next_birthday

  FROM personal
 ) a

 WHERE a.next_birthday < DATE_ADD( NOW(), INTERVAL :interval DAY )

 ORDER BY a.next_birthday ASC

 LIMIT :rangeStart,:limit

说明:next_birthday是根据今年的生日计算的,并根据今年是否已经发生生日而增加1年或0年 - 由IF( DAYOFYEAR( dob ) < DAYOFYEAR( NOW() ), 1, 0 )确定。

http://sqlfiddle.com/#!9/b6471/1的SQLFiddle中查看它的实际效果。播放12月后的1月份的天数。

原始答案......

将以下内容添加到SELECT:

SELECT *
, CASE WHEN MAKEDATE( YEAR( CURRENT_DATE ), DAYOFYEAR( dob ) ) >= CURRENT_DATE
       THEN MAKEDATE( YEAR( CURRENT_DATE ), DAYOFYEAR( dob ) )
       ELSE DATE_ADD( MAKEDATE( YEAR( CURRENT_DATE ), DAYOFYEAR( dob ) ), INTERVAL 1 YEAR )
  END AS next_birthday

然后

ORDER BY next_birthday ASC

重写您的原始查询,例如:

SELECT a.*

  FROM ( SELECT *
              , CASE WHEN DAYOFYEAR( dob ) >= DAYOFYEAR( CURRENT_DATE )
                     THEN MAKEDATE( YEAR( CURRENT_DATE ), DAYOFYEAR( dob ) )
                     ELSE DATE_ADD( MAKEDATE( YEAR( CURRENT_DATE ), DAYOFYEAR( dob ) ), INTERVAL 1 YEAR )
                END AS next_birthday
           FROM personal
       ) a

 WHERE a.next_birthday < DATE_ADD( CURRENT_DATE, INTERVAL :interval DAY )

 ORDER BY a.next_birthday ASC

 LIMIT :rangeStart,:limit

答案 1 :(得分:0)

我现在找到了解决方案。对于那些想知道的人,最终的代码是:

SELECT *, DATE_ADD( dob, INTERVAL YEAR( FROM_DAYS( DATEDIFF( NOW( ), dob) -1 ) ) + 1 YEAR) AS next_birthday
FROM personal
WHERE 1 = ( FLOOR( DATEDIFF( DATE_ADD( DATE( NOW( ) ) , INTERVAL :interval DAY ) , dob ) / 365.25 ) ) -
          ( FLOOR( DATEDIFF( DATE_ADD( DATE( NOW( ) ) , INTERVAL -1 DAY ) , dob ) / 365.25 ) )
ORDER BY next_birthday ASC
LIMIT :rangeStart,:limit

我还没有完全测试过,但是在简单的测试中它可以正常运行。