美文网首页
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