开发者社区> 问答> 正文

mysql中跨月统计考勤天数

如果在数据库中有这么一些数据

人员 请假开始时间 请假结束时间

XX1 2012-10-28 08:30 2012-11-05 17:30

XX2 2012-11-02 08:30 2012-11-07 13:30

XX1 2012-11-08 13:30 2012-11-09 17:30

......多条记录
如何统计某人在11月份的请假时间,剔除休息日11月3、4为周末。

展开
收起
落地花开啦 2016-02-11 17:04:31 4656 0
2 条回答
写回答
取消 提交回答
  • 公益是一辈子的事, I am digoal, just do it. 阿里云数据库团队, 擅长PolarDB, PostgreSQL, DuckDB, ADB等, 长期致力于推动开源数据库技术、生态在中国的发展与开源产业人才培养. 曾荣获阿里巴巴麒麟布道师称号、2018届OSCAR开源尖峰人物.

    如果是PostgreSQL,你可以这样来实现:
    首先需要创建一个剔除周末的函数:

    create or replace function minus_weekend(timestamp, timestamp) returns interval as 
    $$
    
    declare
      s timestamp := $1;
      e timestamp := $2;
      sd date;
      ed date;
      i interval := interval '0';
      x int;
      x1 interval;
      x2 interval;
    begin
      if e < s then
        s := $2;
        e := $1;
      end if;
    
      select case when extract(isodow from s) not in (6,7) then date(s+interval '1 day')-s else interval '0' end, 
             case when extract(isodow from e) not in (6,7) then e-date(e) else interval '0' end
      into x1, x2;
    
      if date(e)-date(s) = 0 then
        if extract(isodow from s) not in (6,7) then
          return e-s;
        else 
          return interval '0';
        end if;
      elsif date(e)-date(s) = 1 then
        return x1 + x2;
      end if;
    
      sd := date(s)+1;
      ed := date(e);
    
      for x in 0..(ed-sd-1) loop
        if extract(isodow from sd+x) not in (6,7) then 
          i := i + interval '1 day';
        end if;
      end loop;
    
      return i+x1+x2;
    end;
    
    $$
     language plpgsql strict;
    

    接下来就可以使用这个函数满足你的需求

    postgres=> create table tbl(username name, begin_time timestamp, end_time timestamp);
    CREATE TABLE
    postgres=> insert into tbl values ('a','2012-10-28 08:30','2012-11-05 17:30');
    INSERT 0 1
    postgres=> insert into tbl values ('b','2012-11-02 08:30', '2012-11-07 13:30');
    INSERT 0 1
    postgres=> insert into tbl values ('a','2012-11-08 13:30', '2012-11-09 17:30');
    INSERT 0 1
    postgres=> select sum(minus_weekend(begin_time,end_time)) from tbl where username='a' ;
           sum       
    -----------------
     5 days 45:30:00
    (1 row)
    2019-07-17 18:40:54
    赞同 1 展开评论 打赏
  • 喜欢技术,喜欢努力的人

    先计数出两个时间的天数,n
    然后得到请假的开始那天是星期几 如 m(0-6)
    然后算出请假的周数 y=(n+m)/7
    计数出不满一周内 放假天数 如果大于5天放假一天
    x=(n+m)%7 >5 ? (n+m)%7 -5 : 0
    n-2y-x:就是请假的天数。

    2019-07-17 18:40:54
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
搭建电商项目架构连接MySQL 立即下载
搭建4层电商项目架构,实战连接MySQL 立即下载
PolarDB MySQL引擎重磅功能及产品能力盛大发布 立即下载

相关镜像