根据当前日期对即将到来的生日进行排序

时间:2011-09-08 06:10:44

标签: mysql sql sorting date datetime

我有下表的人和他们的生日:

name        birthday
----------------------
yannis      1979-06-29
natalia     1980-08-19
kostas      1983-10-27    
christos    1979-07-22
kosmas      1978-04-28

我不知道如何对生日与今天的距离进行排序。所以对于NOW()= 2011-09-08,排序结果应为:

kostas      1983-10-27
kosmas      1978-04-28
yannis      1979-06-29
christos    1979-07-22
natalia     1980-08-19

我正在寻找一个快速黑客,不关心性能(宠物项目 - 表将保存少于1000条记录),但当然每个建议都将非常感激。

5 个答案:

答案 0 :(得分:10)

这是一种方式:

  • 计算当前年度 - 出生年份
  • 将生成的年数添加到出生日期
  • 你现在今年过生日了,如果这个日期过去了,那就再加一年
  • 按日期对结果进行排序
SELECT
    name,
    birthday,
    birthday + INTERVAL (YEAR(CURRENT_DATE) - YEAR(birthday))     YEAR AS currbirthday,
    birthday + INTERVAL (YEAR(CURRENT_DATE) - YEAR(birthday)) + 1 YEAR AS nextbirthday
FROM birthdays
ORDER BY CASE
    WHEN currbirthday >= CURRENT_DATE THEN currbirthday
    ELSE nextbirthday
END

注意:

  • 今天的生日首先出现,无论当前时间如何
  • 2月29日生日被视为相当于2月28日生日的常年,例如
    • 在2019年1月1日,2月28日和2月29日生日(2019年)排序等于
    • 在3月1日/ 1月2日2月28日和2月29日生日(2020)按预期排序

SQLFiddle

答案 1 :(得分:5)

SELECT name
     , birthday
FROM TableX
ORDER BY DAYOFYEAR(birthday) < DAYOFYEAR(CURDATE())
       , DAYOFYEAR(birthday)

不,由于366天的年数,以上可能会产生错误结果。这是正确的:

SELECT name
     , birthday
FROM
  ( SELECT name
         , birthday
         , MONTH(birthday) AS m
         , DAY(birthday) As d
    FROM TableX
  ) AS tmp
ORDER BY (m,d) < ( MONTH(CURDATE()), DAY(CURDATE()) )
       , m
       , d

如果你的桌子增长到几千条记录,它将会非常慢。如果您想要快速查询,请添加包含月和日的字段,并在(bmonth,bday)上添加索引,或将其添加为一个字段,Char(08-170817为8月17日)或Int({8}的817)和该字段的索引。

答案 2 :(得分:4)

似乎相当快,闰年没问题:

SELECT * 
FROM `people` 
ORDER BY CONCAT(SUBSTR(`birthday`,6) < SUBSTR(CURDATE(),6), SUBSTR(`birthday`,6))

Всегениальное - просто! ;)

答案 3 :(得分:2)

不漂亮,但有效

SELECT * 
,CASE WHEN BirthdayThisYear>=NOW() THEN BirthdayThisYear ELSE BirthdayThisYear + INTERVAL 1 YEAR END AS NextBirthday
FROM (
    SELECT * 
    ,birthday - INTERVAL YEAR(birthday) YEAR + INTERVAL YEAR(NOW()) YEAR AS BirthdayThisYear
    FROM bd
) AS bdv
ORDER BY NextBirthday

答案 4 :(得分:0)

我会这样尝试(但未经测试):

SELECT
  name,
  birthday
FROM
  birthdays
ORDER BY
  ABS( DAYOFYEAR(birthday) - (DAYOFYEAR(CURDATE()) ) ASC

修改
将排序从DESC更改为ASC,因为您希望获得最远的,而不是最接近的。