MySQL如何查询跨年度日期范围内的生日(忽略年份)
解决跨年度生日范围查询问题
问题根源
你的原SQL把所有生日都绑定到同一个年份(比如2023),当查询范围跨年度时(如2023-12-15到2024-01-10),次年1月的生日会被转换成2023-01-xx,自然不在目标范围内,导致查询失效。
解决方案
下面提供两种可行的解决思路,均能覆盖跨年度场景:
方法一:基于MMDD数值的年无关判断
这种思路将日期转换为MMDD格式的整数(如12月15日为1215,1月10日为0110),通过数值比较判断生日是否在范围内,无需纠结年份和闰年问题:
SELECT * FROM `users` WHERE CASE -- 范围不跨年度:直接判断MMDD在区间内 WHEN DATE_FORMAT('2023-12-15 00:00:00', '%m%d') <= DATE_FORMAT('2024-01-10 23:59:59', '%m%d') THEN DATE_FORMAT(CONCAT_WS('-', 2000, dob_month, dob_day), '%m%d') BETWEEN DATE_FORMAT('2023-12-15 00:00:00', '%m%d') AND DATE_FORMAT('2024-01-10 23:59:59', '%m%d') -- 范围跨年度:判断MMDD大于等于起始值 或 小于等于结束值 ELSE DATE_FORMAT(CONCAT_WS('-', 2000, dob_month, dob_day), '%m%d') >= DATE_FORMAT('2023-12-15 00:00:00', '%m%d') OR DATE_FORMAT(CONCAT_WS('-', 2000, dob_month, dob_day), '%m%d') <= DATE_FORMAT('2024-01-10 23:59:59', '%m%d') END
注:用2000年拼接生日是因为2000是闰年,能正确处理2月29日的生日格式转换。
方法二:分年度生成生日日期判断
如果需要严格对应年份的日期逻辑,可以针对跨年度场景分别生成起始年和结束年的生日日期,再判断是否落在范围内:
SELECT * FROM `users` WHERE CASE -- 范围不跨年度:用起始年拼接生日判断区间 WHEN YEAR('2023-12-15 00:00:00') = YEAR('2024-01-10 23:59:59') THEN DATE(CONCAT_WS('-', YEAR('2023-12-15 00:00:00'), dob_month, dob_day)) BETWEEN '2023-12-15 00:00:00' AND '2024-01-10 23:59:59' -- 范围跨年度:判断起始年的生日>=起始日期 或 结束年的生日<=结束日期 ELSE DATE(CONCAT_WS('-', YEAR('2023-12-15 00:00:00'), dob_month, dob_day)) >= '2023-12-15 00:00:00' OR DATE(CONCAT_WS('-', YEAR('2024-01-10 23:59:59'), dob_month, dob_day)) <= '2024-01-10 23:59:59' END
补充:如果需要处理2月29日的闰年问题,可以在生成日期时加入判断,将非闰年的2月29日转换为2月28日或3月1日,具体逻辑可根据业务需求调整。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

