我正在寻找将给定日期增加工作日数的功能。
假期表
create table pyha (pyha date primary key) ; insert into pyha values ('2018-12-24'),('2018-12-25'),('2018-12-26'),('2019-01-01');
包含假期。另外,星期六和星期日均为非营业日。
我试图创建功能
create or replace function add_business_day(from_date date, num_days int) returns date as $fbd$ with days as ( select dd, extract(DOW from dd) dw from generate_series(($1+ interval'1day')::date, ($1+ interval'1day'*$2+interval'10days')::date , '1 day'::interval) dd ) select min(dd)::date from days where dw not in (6,0) and dd not in (select pyha from pyha) and dd>=$1+interval'1day'*$2+ interval'1day'*(select count(*) from pyha where pyha between $1+ interval'1day' and $1+interval'1day'*$2 ) $fbd$ language sql;
但是它有时返回不正确的结果:
add_business_day('2018-12-08',2)
返回2018-12-10, 但正确的结果是2018-12-11
如何在Postgres 9.1+中创建这样的功能?
关键是生成一系列工作日,并用row_number()以下编号对它们进行编号:
row_number()
create or replace function add_business_day(from_date date, num_days int) returns date as $fbd$ select d from ( select d::date, row_number() over (order by d) from generate_series(from_date+ 1, from_date+ num_days* 2+ 5, '1d') d where extract('dow' from d) not in (0, 6) and d not in (select pyha from pyha) ) s where row_number = num_days $fbd$ language sql;
测试查询的结果似乎正确:
select days, add_business_day('2018-12-08', days) from generate_series(1, 20) days days | add_business_day ------+------------------ 1 | 2018-12-10 2 | 2018-12-11 3 | 2018-12-12 4 | 2018-12-13 5 | 2018-12-14 6 | 2018-12-17 7 | 2018-12-18 8 | 2018-12-19 9 | 2018-12-20 10 | 2018-12-21 11 | 2018-12-27 12 | 2018-12-28 13 | 2018-12-31 14 | 2019-01-02 15 | 2019-01-03 16 | 2019-01-04 17 | 2019-01-07 18 | 2019-01-08 19 | 2019-01-09 20 | 2019-01-10 (20 rows)
或者,您可以在循环中找到日期:
create or replace function add_business_day_loop(from_date date, num_days int) returns date as $fbd$ begin while num_days > 0 loop from_date:= from_date+ 1; while from_date in (select pyha from pyha) or extract('dow' from from_date) in (0, 6) loop from_date:= from_date+ 1; end loop; num_days:= num_days- 1; end loop; return from_date; end; $fbd$ language plpgsql;