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

yan*_*nis 5 mysql sql sorting datetime date

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

name        birthday
----------------------
yannis      1979-06-29
natalia     1980-08-19
kostas      1983-10-27    
christos    1979-07-22
kosmas      1978-04-28
Run Code Online (Sandbox Code Playgroud)

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

kostas      1983-10-27
kosmas      1978-04-28
yannis      1979-06-29
christos    1979-07-22
natalia     1980-08-19
Run Code Online (Sandbox Code Playgroud)

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

Sal*_*n A 11

这是一种方式:

  • 计算当前年 - 出生年份
  • 将生成的年数添加到出生日期
  • 你现在有了今年的生日,如果这个日期已经过去,那么再加一年
  • 按该日期对结果进行排序
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
Run Code Online (Sandbox Code Playgroud)

笔记:

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

SQLFiddle


ype*_*eᵀᴹ 5

SELECT name
     , birthday
FROM TableX
ORDER BY DAYOFYEAR(birthday) < DAYOFYEAR(CURDATE())
       , DAYOFYEAR(birthday)
Run Code Online (Sandbox Code Playgroud)

不,以上可能会产生错误结果,因为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
Run Code Online (Sandbox Code Playgroud)

如果你的表增长到几千条记录,它将会非常慢.如果您想要快速查询,请添加包含月份和日期的字段并打开索引,(bmonth,bday)或将它们添加为一个字段,Char(08-17081717-Aug)或Int(81717-Aug)以及该字段的索引.