美文网首页
mysql查找当前月份的第一个和最后一个星期一

mysql查找当前月份的第一个和最后一个星期一

作者: Taodede | 来源:发表于2018-10-16 15:27 被阅读58次

之前,已经向大家介绍了一些mysql的常用日期函数https://www.jianshu.com/p/93251dbc7278
以及使用这些函数实现的稍复杂的日期查询https://www.jianshu.com/p/bcfd72967681
本次将在日期函数的组合使用上,加强逻辑复杂性,要实现的查询目标为:
查找当前月份的第一个和最后一个星期一
基本逻辑为:
①查找当前月份的第一天
②若第一天为星期五,则返回当前月份;若>星期一,为(星期二到星期六)则查找下周的星期一;若第一天为星期天,则在第一天基础上加一天即为星期一;
需要注意的是,在dayofweek()函数中,星期天=1,星期一=2.......
③在第一个星期一基础上加28天,如果还在该月之内,则为最后一个星期一;如果已经不在该月,则在第一个星期一基础上加21,即可得该月最后一个星期一;

首先查找当前月份的第一天

mysql> select date_add(
    ->                 date_add(current_date(),interval -day(current_date()) day),
    ->                 interval 1 day) as first_day,
    ->        month(current_date()) as current_month;
+------------+---------------+
| first_day  | current_month |
+------------+---------------+
| 2018-10-01 |            10 |
+------------+---------------+
1 row in set (0.01 sec)

解析:内部date_add(current_date(),interval -day(current_date()) day) 表示当前日期减去当前处于该月的第几天,可求得上月的最后一天;
date_add(
-> date_add(current_date(),interval -day(current_date()) day),
-> interval 1 day) as first_day
在上月最后一天的基础上加1,即可求得当前月份的第一天。

接下来查找当前月份的第一个星期一:
这里涉及到几个函数,首先为大家介绍一下
case when end是一个条件函数,可通过设置多个条件限定返回值;
sign(expr) 当expr==0,则sign()返回0,expr>0,sign()返回1,expr<0,sign() 返回-1;

mysql> select case sign(dayofweek(first_day)-2)
    ->             when  0 then first_day
    ->             when -1 then date_add(first_day,interval 1 day)
    ->             when  1 then date_add(first_day,interval (7-(dayofweek(first_day)-2)) day)
    ->         end as first_monday , current_month
    -> from (
    ->  select date_add(
    ->                  date_add(current_date(),interval -day(current_date()) day),
    ->                  interval 1 day) as first_day, 
    ->          month(current_date()) as current_month)a;
+--------------+---------------+
| first_monday | current_month |
+--------------+---------------+
| 2018-10-01   |            10 |
+--------------+---------------+
1 row in set (0.00 sec)

解析:
从内向外看,在第一步中我们获取了当月第一天first_day和当前月份current_month;
由于dayofweek(星期一)取值为2,因此在case when函数中,首先判断,
~~若dayofweek(first_day)-2=0,则代表first_day为第一个星期一;
~~若dayofweek(first_day)-2<0,只有一种可能,dayofweek(first_day)=1,即本月第一天为星期天,在此基础上加1则是本月第一个星期一为:date_add(first_day,interval 1 day);
~~若dayofweek(first_day)-2>0,先计算当前日期距离星期一有几天dayofweek(first_day)-2),再用7减去差值,可得距离下周的星期一有几天,在本月第一天的基础上加上这个差值即可date_add(first_day,interval (7-(dayofweek(first_day)-2)) day);

最后求本月的最后一个星期一:

mysql> select first_monday,
    -> case month(date_add(first_monday,interval 28 day))
    ->      when current_month then date_add(first_monday,interval 28 day)
    ->      else date_add(first_monday,interval 21 day)
    -> end as last_monday
    -> from(
    ->  select case sign(dayofweek(first_day)-2)
    ->              when  0 then first_day
    ->              when -1 then date_add(first_day,interval 1 day)
    ->              when  1 then date_add(first_day,interval (7-(dayofweek(first_day)-2)) day)
    ->          end as first_monday , current_month
    ->  from (
    ->   select date_add(
    ->                   date_add(current_date(),interval -day(current_date()) day),
    ->                   interval 1 day) as first_day,
    ->           month(current_date()) as current_month
    ->        )a
    ->        )b;
+--------------+-------------+
| first_monday | last_monday |
+--------------+-------------+
| 2018-10-01   | 2018-10-29  |
+--------------+-------------+
1 row in set (0.00 sec)

解析:
一个月最多有四个完整周
当本月第一个星期一加上28仍在本月内时,即可得最后一个星期一;
当本月第一个星期一加上28不在本月内时,则上周的星期一为本月最后一个星期一;

相关文章

网友评论

      本文标题:mysql查找当前月份的第一个和最后一个星期一

      本文链接:https://www.haomeiwen.com/subject/nzlhzftx.html