目录
直接查看结果
最近做项目遇到一个看起来很简单的需求——按周统计一个月内的关卡延期次数,这里我需要得到一个日期是它所在月份的周次,如今天'2022-05-27'是本月的第5周。
本来我觉得很简单,但是写起来确实有些许复杂,这里记录一下我写它的思路。
如果有方便的写法,请大佬指出,这个写法确实挺让我头疼的!!
我们先定义一个日期变量@date:
SET @date='2022-05-27';
我们知道DAY()函数可以返回一个日期是当月的第几天,如'2022-05-27'返回的结果是27:
SELECT DAY(@date);
然后我们就可以获取到这个月的第一天,就是@date减去(它的day-1),这个工作可以交给DATE_SUB()函数完成:
SELECT DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY);
我们可以使用WEEKDAY()函数来获取x月1日的星期数,周一返回0、周二返回1....
则如果x月1日是周一我们不需要操作,如果x月1日不是周一,我们需要对x月1日增加(1-WEEKDAY(x月1日))天,这个判断我们可以使用mysql的IF()函数完成。
IF()函数有三个参数,第一个参数是表达式是一个布尔值,当第一个参数为true时返回第二个参数值,当第一个参数为false时返回第三个参数值。需要注意的是,mysql跟c语言相同,可以使用数值类型表示布尔值,数值0表示false,非0值表示true,于是我们可以获取到x月的第一个周一:
SELECT DATE_ADD(DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY),
INTERVAL IF(WEEKDAY(DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY)),
7-WEEKDAY(DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY)),
0)
DAY);
获取到第一个周一以后的事情就方便了,FLOOR((输入的日期-第一个周一的日期)/7)就可以知道距离第一周有几周
SELECT FLOOR(DATEDIFF(@DATE,
DATE_ADD(DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY),
INTERVAL IF(WEEKDAY(DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY)),
7-WEEKDAY(DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY)),
0)
DAY)
)/7);
当x月1日是周一时需要对这个周数加1,当x月1日不是周一时需要对这个周数加2
SELECT FLOOR(DATEDIFF(@DATE,DATE_ADD(DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY),
INTERVAL IF(WEEKDAY(DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY)),
7-WEEKDAY(DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY)),
0) DAY
)
)/7
)+IF(WEEKDAY(DATE_SUB(@date,INTERVAL (DAY(@date)-1) DAY)),2,1);
运行无误
可恶啊!博客写着写着发现我之前的sql语句有问题,改代码去了,555555~