mysql 查询当月过生日_MySql查询本周/月或下周/月过生日的人

头一次遇到这个问题,想了好久(由于对于mysql的日期参数不熟悉),随后在网上查询,发现网上的解法千奇百怪,评论区也频频翻车,争论不断,主要原因是算法中存在考虑不周的问题。这种错误主要可以总结为一下几点:直接计算周数不考虑年份

这样的解法看似没有很大问题,甚至基于巧合可能在数据量较小的情况下测试集可以完全通过,但是存在不小的隐患。例如:1994年的11月14日 为1994年的第47周 星期1

2020年的11月14日 为2020年的第46周 星期6

因此若有人为1994年11月14日出生,按照2020年计算应该在2020年第46周(当前周)过生日,但是如果直接计算周数不考虑年份的化如下所示,则会产生不在此周过生日的结论。

当然此现象这和函数选取周几作为一周的开始密切相关,但是不论选择周日为一周的第一天还是周一作为一周的第一天,总会找到如上不同年份相同日月周数恰好错开一周的情况。因此此情况较为难以发现,在未使用大量数据之前,只有偶发的可能性。

select * from student
where WEEKOFYEAR(student.Sage)=WEEKOFYEAR(CURDATE());

代码源 直接利用天数计算周始周末

在得到当前天所对应的周数时,认为当前天-7即为本周的开始,存在鲜明的bug。例如:假设当前日期为2020年11月11日,则周始周末应该为:正确的: 2020年11月8日(46周) —> 2020年11月14日(46周)

错误的: 2020年11月4日(45周) —> 2020年11月11日(46周)

因此将-7作为周始周末区间作为判断的一定会存在问题,代码示例如下:最后一部的where条件中将DAYOFWEEK(CURDATE())和DAYOFWEEK(CURDATE())-7作为一周的开始结束。但是下方的语句已经将不同年份的日期统一转换至当前年份的,避免了第一种隐形错误。

SELECT A.sid,A.sname FROM

(SELECT sid,sname,

DATEDIFF(CURDATE(),ADDDATE(sage,INTERVAL YEAR(CURDATE()) - YEAR(sage) YEAR)) diff

FROM student) A

WHERE A.diff < DAYOFWEEK(CURDATE()) AND A.diff >= DAYOFWEEK(CURDATE()) - 7;

代码源

个人采用的解题思路综合以上两种,取长补短:首先转换不同年份的日期统一转换至当前年份,其次使用week/weekofyear函数与当前日期周比较,便可得到当前周生日的人,若要求下周或者下个月直接当前周/月后面+1即可:

首先初始化表,代码如下:

create table Student(SId varchar(10),Sname varchar(10),Sage datetime,Ssex varchar(10));

insert into Student values(‘01’ , ‘赵雷’ , ‘1990-01-01’ , ‘男’);

insert into Student values(‘02’ , ‘钱电’ , ‘1990-12-21’ , ‘男’);

insert into Student values(‘03’ , ‘孙风’ , ‘1990-12-20’ , ‘男’);

insert into Student values(‘04’ , ‘李云’ , ‘1990-12-06’ , ‘男’);

insert into Student values(‘05’ , ‘周梅’ , ‘1991-12-01’ , ‘女’);

insert into Student values(‘06’ , ‘吴兰’ , ‘1992-01-01’ , ‘女’);

insert into Student values(‘07’ , ‘郑竹’ , ‘1989-01-01’ , ‘女’);

insert into Student values(‘09’ , ‘张三’ , ‘2017-12-20’ , ‘女’);

insert into Student values(‘10’ , ‘李四’ , ‘2017-12-25’ , ‘女’);

insert into Student values(‘11’ , ‘李四’ , ‘2012-06-06’ , ‘女’);

insert into Student values(‘12’ , ‘赵六’ , ‘2013-06-13’ , ‘女’);

insert into Student values(‘13’ , ‘孙七’ , ‘2014-06-01’ , ‘女’);

查询本周过生日的学生

SELECT * FROM student
WHERE WEEK(CONCAT(YEAR(CURDATE()),"-" ,MID(sage,6,5))) = WEEK(NOW())

# 1、选取原生日里的月日成分(按照字符串进行处理)

# >>> MID(sage,6,5)

# 2、将选取的月日成分与今年的年份相接

# >>> CONCAT(YEAR(CURDATE()),"-" ,MID(sage,6,5))

查询下周过生日的学生

SELECT * FROM student AS s

WHERE WEEK(CONCAT(YEAR(CURDATE()),"-",MID(s.sage,6,5))) = WEEK(CURDATE())+1

查询本月/下月过生日的学生

SELECT * FROM student AS s

WHERE MONTH(CONCAT(YEAR(CURDATE()),"-",MID(s.sage,6,5))) = MONTH(CURDATE())

# 改用 month函数,查询下月过生日则+1

猜你喜欢

转载自blog.csdn.net/m0_46267375/article/details/120393465