在postgres中给出2个时间戳,如何在不计算整个星期六和星期日的情况下计算时差?
OR
如何计算给定时间间隔内星期六和星期日的数量?
答案 0 :(得分:5)
以下函数返回两个日期之间的完整周末天数。由于需要整天,您可以在调用函数之前将时间戳转换为日期。如果第一个日期不是严格地在第二个日期之前,则返回0。
CREATE FUNCTION count_full_weekend_days(date, date)
RETURNS int AS
$BODY$
SELECT
($1 < $2)::int
*
(
(($2 - $1) / 7) * 2
+
(EXTRACT(dow FROM $1)<6 AND EXTRACT(dow FROM $2)>0 AND EXTRACT(dow FROM $1)>EXTRACT(dow FROM $2))::int * 2
+
(EXTRACT(dow FROM $1)=6 AND EXTRACT(dow FROM $2)>0)::int
+
(EXTRACT(dow FROM $2)=0 AND EXTRACT(dow FROM $1)<6)::int
);
$BODY$
LANGUAGE 'SQL' IMMUTABLE STRICT;
示例:
SELECT COUNT_FULL_WEEKEND_DAYS('2009-04-10', '2009-04-20');
# returns 4
SELECT COUNT_FULL_WEEKEND_DAYS('2009-04-11', '2009-04-20');
# returns 3 (11th is Saturday, so it shouldn't be counted as full day)
SELECT COUNT_FULL_WEEKEND_DAYS('2009-04-12', '2009-04-20');
# returns 2 (12th is Sunday, so it shouldn't be counted as full day)
SELECT COUNT_FULL_WEEKEND_DAYS('2009-04-13', '2009-04-20');
# returns 2
要获得除整个周末天数之外的天数,只需从上述函数中减去天数:
SELECT
'2009-04-20'::date
-
'2009-04-13'::date
-
COUNT_FULL_WEEKEND_DAYS('2009-04-13', '2009-04-20');
答案 1 :(得分:2)
您可能会发现这非常有用:
CREATE OR REPLACE FUNCTION working_days(date, date) RETURNS INT AS
$$
SELECT COUNT(days)::INT
FROM generate_series($1, $2, '1 day') AS days
WHERE EXTRACT(DOW FROM days) NOT IN(0, 6);
$$
LANGUAGE 'sql' IMMUTABLE STRICT;
答案 2 :(得分:1)
(天/ 7)* 2 +最后一天(天%7天)的坐/太阳次数。
答案 3 :(得分:1)
这应该回答你问题的第二部分:
create or replace function is_weekend_day(date) returns boolean
strict immutable language 'sql'
as $$ select case extract(dow from $1) when 0 then true when 6 then true else false end $$;
create or replace function count_weekend_days(start_date date, end_date date) returns int
strict immutable language 'sql'
as $$
select cast(sum(case when is_weekend_day($1 + ofs) then 1 else 0 end) as int)
from generate_series(0, $2 - $1) ofs
$$;
之后制作相应的count_non_weekend_days
很简单。
答案 4 :(得分:1)
最好的解决方案是使用日历表。这非常有用,您可以做各种有趣的事情 - 包括计算两个日期之间的工作日数或计算两个日期之间的假期数。
此表通常会提前填写 - 例如20年,并且知名假日的日期会被适当标记。如果假期发生变化,您可以偶尔维护一下表格,将日期标记为假期。 More info here和here。这使用MS SQL Server,但也可以轻松移植。
答案 5 :(得分:0)
您可能会发现此博文有用:{{3p>
答案 6 :(得分:0)
这将计算两个日期之间某一天的数量:
-- 0 Sunday
-- 1 Monday
-- 2 Tuesday
-- 3 Wednesday
-- 4 Thursday
-- 5 Friday
-- 6 Saturday
WITH rng AS (
SELECT
'march 3 2013'::date AS start,
'march 3 2014'::date AS end,
0 AS day -- Sunday
)
SELECT count(1)
FROM rng, generate_series(0, (extract(epoch from age(rng.end, rng.start)) / (60*60*24))::int) AS n
WHERE extract(dow from rng.start + (n * '1 day'::interval)) = rng.day
答案 7 :(得分:0)
我建议你创建一个随时随地使用的函数; )
上面的代码将创建一个sql函数,用于计算并返回周末天数(周六,周日)。 只是你可以更灵活地使用这个功能。
CREATE OR REPLACE FUNCTION <YourSchemaNameOptional>.count_full_weekend_days(date, date)
RETURNS bigint AS
$BODY$
select COUNT(MySerie.*) as Qtde
from (select CURRENT_DATE + i as Date, EXTRACT(DOW FROM CURRENT_DATE + i) as DiaDate
from generate_series(date ($1) - CURRENT_DATE, date ($2) - CURRENT_DATE ) i) as MySerie
WHERE MySerie.DiaDate in (6,0);
$BODY$
LANGUAGE 'SQL' IMMUTABLE STRICT;
之后,您可以使用功能在一个间隔中仅返回周末天数。 以下是使用示例:
SELECT <YourSchemaNameOptional>.count_full_weekend_days('2017-09-11', '2017-09-25') as days; --> RES: 4
此选择必须返回4,因为第一天和第二天是星期一,我们之间有2个星期六和2个星期日。
现在,仅返回工作日(没有周末),如您所愿,只需进行减法,如下例所示:
SELECT (date '2017-09-25' - date '2017-09-11' ) - <YourSchemaName>.count_full_weekend_days('2017-09-11', '2017-09-25'); --> RES: 14 - 4 = 10