我正在尝试找到一种将工作日添加到任何日期的方法。一个例子是:
date = '2017-04-28' (It was a Friday)
date + 2 = '2017-05-02' (It skipped Saturday and Sunday)
Run Code Online (Sandbox Code Playgroud)
有没有办法在没有自定义查询的情况下做到这一点?
您可以使用generate_series()生成一系列日期,并使用extract()获取星期几。
然后简单地过滤那些星期几不是 0=星期日,6=星期六的日期。
Run Code Online (Sandbox Code Playgroud)with days as ( select dd, extract(DOW from dd) dw from generate_series('2017-04-28'::date, '2017-05-02'::date, '1 day'::interval) dd ) select * from days where dw not in (6,0);
日 | 体重 :--------------------- | :- 2017-04-28 00:00:00+01 | 5 2017-05-01 00:00:00+01 | 1 2017-05-02 00:00:00+01 | 2
dbfiddle在这里
如果必须排除公共假期和其他非工作日,可以建business_day
表。只需插入上面的输出,然后删除所有必须排除的天数(在某些国家/地区,例如匈牙利,也可能需要添加额外的替换天数(通常是星期六))。当然,这必须维护(例如,您可以在每年 12 月准备下一年),但是由于没有内置功能可以了解那些日子,因此您没有更好的选择。
使用日历表
让我创建一个示例calendar
表并插入一些值:
create table calendar
(
id serial primary key,
cal_day date not null,
bussines_day bool not null
);
insert into calendar (cal_day, bussines_day) values
('20180101', false), ('20180102', true),
('20180103', false), ('20180104', true),
('20180105', false), ('20180106', true),
('20180107', false), ('20180108', true),
('20180109', false), ('20180110', true),
('20180111', false), ('20180112', true);
Run Code Online (Sandbox Code Playgroud)
现在您可以使用函数以这种方式获取下一个第 N 个工作日:
create or replace function add_business_day(from_date date, num_days int)
returns date
as $fbd$
select max(cal_day) as the_day
from (select cal_day
from calendar
where cal_day > $1
and business_day = true
order by cal_day
limit $2) bd;
$fbd$ language sql;
Run Code Online (Sandbox Code Playgroud)
或者
create or replace function add_business_day2(from_date date, num_days int)
returns date
as $fbd$
select cal_day
from (select cal_day,
row_number() over (order by cal_day) rn
from calendar
where cal_day > $1
and business_day = true
limit $2) bd
where rn = $2;
$fbd$ language sql;
Run Code Online (Sandbox Code Playgroud)
两者都返回相同的结果:
Run Code Online (Sandbox Code Playgroud)select add_business_day('20180103', 4);
| add_business_day | | :--------------- | | 2018-01-10 |
Run Code Online (Sandbox Code Playgroud)select add_business_day2('20180103', 4)
| add_business_day2 | | :---------------- | | 2018-01-10 |
db<>在这里摆弄