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

计算a用户实际工作时间。

postgres=> select minus_weekend(begin_time,end_time),username from tbl where username='a';
  minus_weekend  | username 
-----------------+----------
 5 days 17:30:00 | a
 28:00:00        | a
(2 rows)

postgres=> select sum(minus_weekend(begin_time,end_time)) from tbl where username='a' ;
       sum       
-----------------
 5 days 45:30:00
(1 row)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值