计算工作日 PostgresQL
Counting Business Days PostgresSQL
我正在尝试做这样的事情:
SELECT t.id, t.startdate, t.enddate, FOO
FROM table
其中“Foo”是一些sql 计算开始日期和结束日期之间的工作日的胡言乱语,如下所示:
+----+------------+------------+--------------+
| id | startdate | enddate | businessdays |
+----+------------+------------+--------------+
| 1 | 2020-09-12 | 2020-09-28 | 11 |
| 2 | 2020-09-02 | 2020-09-28 | 19 |
| 3 | 2020-09-22 | 2020-09-28 | 5 |
+----+------------+------------+--------------+
我能够毫不费力地创建一个函数:
CREATE OR REPLACE FUNCTION getbusinessday(startdate date, enddate date DEFAULT current_date) RETURNS int
LANGUAGE plpgsql
AS
$$
DECLARE
daycount integer;
BEGIN
SELECT COUNT(i)
INTO daycount
FROM generate_series(startdate,enddate,'1 day') i
WHERE EXTRACT(DOW FROM i) NOT IN (0, 6);
RETURN daycount;
END;
$$;
有没有不用这个函数就能实现的方法?
加分问题:
是否可以允许输入时间戳并在实际函数中强制转换为日期?我只是好奇。
您可以用横向连接替换函数:
select t.*, x.*
from mytable t
cross join lateral (
select count(*) businessdays
from generate_series(t.startdate, coalesce(t.enddate, current_date), '1 day') x(dt)
where extract (dow from x.dt) not in (0, 6)
) x
我不确定你关于 timestamp/date 选角的问题。如果您的列有时间成分,而您不想考虑它,那么您可以输入 generate_series()
:
from generate_series(t.startdate::date, coalesce(t.enddate::date, current_date), '1 day') x(dt)
我正在尝试做这样的事情:
SELECT t.id, t.startdate, t.enddate, FOO
FROM table
其中“Foo”是一些sql 计算开始日期和结束日期之间的工作日的胡言乱语,如下所示:
+----+------------+------------+--------------+
| id | startdate | enddate | businessdays |
+----+------------+------------+--------------+
| 1 | 2020-09-12 | 2020-09-28 | 11 |
| 2 | 2020-09-02 | 2020-09-28 | 19 |
| 3 | 2020-09-22 | 2020-09-28 | 5 |
+----+------------+------------+--------------+
我能够毫不费力地创建一个函数:
CREATE OR REPLACE FUNCTION getbusinessday(startdate date, enddate date DEFAULT current_date) RETURNS int
LANGUAGE plpgsql
AS
$$
DECLARE
daycount integer;
BEGIN
SELECT COUNT(i)
INTO daycount
FROM generate_series(startdate,enddate,'1 day') i
WHERE EXTRACT(DOW FROM i) NOT IN (0, 6);
RETURN daycount;
END;
$$;
有没有不用这个函数就能实现的方法?
加分问题:
是否可以允许输入时间戳并在实际函数中强制转换为日期?我只是好奇。
您可以用横向连接替换函数:
select t.*, x.*
from mytable t
cross join lateral (
select count(*) businessdays
from generate_series(t.startdate, coalesce(t.enddate, current_date), '1 day') x(dt)
where extract (dow from x.dt) not in (0, 6)
) x
我不确定你关于 timestamp/date 选角的问题。如果您的列有时间成分,而您不想考虑它,那么您可以输入 generate_series()
:
from generate_series(t.startdate::date, coalesce(t.enddate::date, current_date), '1 day') x(dt)