我有一张包含姓名和出生日期的表。
我想获取与下一个即将到来的生日相对应的名称。 (其中n是整数)
使用LIMIT(我不想限制行数),使用BETWEEN或WHERE子句都不可能,因为这不是在有限的时间内完成的。
谢谢你的帮助

最佳答案

以下查询...

1)首先对不同的Dob进行排序(默认情况下,今天首先排序)。

2)使用LIMIT功能选择第一个Dob,然后

3)最后,选择所有具有最早5个dob的用户。

SELECT u1.*
from USERS u1
INNER JOIN
(
    SELECT DISTINCT
      EXTRACT(MONTH FROM dob) dob_month,
      EXTRACT(DAY FROM dob) dob_day
    FROM users
    ORDER BY
    CASE
      WHEN EXTRACT(MONTH FROM dob) = EXTRACT(MONTH FROM CURDATE()) AND EXTRACT(DAY FROM dob) = EXTRACT(DAY FROM CURDATE()) THEN 1
      WHEN EXTRACT(MONTH FROM dob) = EXTRACT(MONTH FROM CURDATE()) AND EXTRACT(DAY FROM dob) < EXTRACT(DAY FROM CURDATE()) THEN -1
      ELSE SIGN(EXTRACT(MONTH FROM dob) - EXTRACT(MONTH FROM CURDATE()))
    END DESC,
    CASE
      WHEN EXTRACT(MONTH FROM dob) = EXTRACT(MONTH FROM CURDATE()) AND EXTRACT(DAY FROM dob) = EXTRACT(DAY FROM CURDATE()) THEN 1
      ELSE SIGN(EXTRACT(DAY FROM dob) - EXTRACT(DAY FROM CURDATE()))
    END DESC,
    EXTRACT(MONTH FROM dob) ASC,
    EXTRACT(DAY FROM dob) ASC
  LIMIT 5
) selected_dobs
ON EXTRACT(MONTH FROM u1.dob) = selected_dobs.dob_month and EXTRACT(DAY FROM u1.dob) = selected_dobs.dob_day
ORDER BY
    CASE
      WHEN EXTRACT(MONTH FROM dob) = EXTRACT(MONTH FROM CURDATE()) AND EXTRACT(DAY FROM dob) = EXTRACT(DAY FROM CURDATE()) THEN 1
      WHEN EXTRACT(MONTH FROM dob) = EXTRACT(MONTH FROM CURDATE()) AND EXTRACT(DAY FROM dob) < EXTRACT(DAY FROM CURDATE()) THEN -1
      ELSE SIGN(EXTRACT(MONTH FROM dob) - EXTRACT(MONTH FROM CURDATE()))
    END DESC,
    CASE
      WHEN EXTRACT(MONTH FROM dob) = EXTRACT(MONTH FROM CURDATE()) AND EXTRACT(DAY FROM dob) = EXTRACT(DAY FROM CURDATE()) THEN 1
      ELSE SIGN(EXTRACT(DAY FROM dob) - EXTRACT(DAY FROM CURDATE()))
    END DESC,
    EXTRACT(MONTH FROM dob) ASC,
    EXTRACT(DAY FROM dob) ASC,
    username ASC;


SQL Fiddle demo

注意

没有从SELECT过滤掉任何行,因为接下来的5个生日(部分或全部)可能发生在下一个日历年(例如,今天可能是12月28日,而接下来的5个生日可能发生在12月29日, 1月2日,1月2日,1月5日,1月6日)。

如果您希望在列表的底部(而不是上面的查询中的列表的顶部)选择今天的生日,只需在ORDER BY子句中将1更改为-1,如下所示

ORDER BY CASE WHEN EXTRACT(MONTH FROM dob) = EXTRACT(MONTH FROM CURDATE()) AND EXTRACT(DAY FROM dob) = EXTRACT(DAY FROM CURDATE()) THEN -1 WHEN EXTRACT(MONTH FROM dob) = EXTRACT(MONTH FROM CURDATE()) AND EXTRACT(DAY FROM dob) < EXTRACT(DAY FROM CURDATE()) THEN -1 ELSE SIGN(EXTRACT(MONTH FROM dob) - EXTRACT(MONTH FROM CURDATE())) END DESC, CASE WHEN EXTRACT(MONTH FROM dob) = EXTRACT(MONTH FROM CURDATE()) AND EXTRACT(DAY FROM dob) = EXTRACT(DAY FROM CURDATE()) THEN -1 ELSE SIGN(EXTRACT(DAY FROM dob) - EXTRACT(DAY FROM CURDATE())) END DESC, EXTRACT(MONTH FROM dob) ASC, EXTRACT(DAY FROM dob) ASC

关于mysql - MYSQL-即将到来的X生日,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24475232/

10-12 01:35