2009-04-14 50 views

答えて

5

次の関数は、2つの日付の間の完全な週末の日数を返しています。フルデイが必要な場合は、関数を呼び出す前に日付にタイムスタンプをキャストすることができます。最初の日付が厳密に2番目の日付の前にない場合は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

(日/ 7)* 2 +最後の日の日数(日%7)* 2。

1

これは、あなたの質問の後半部分に答える必要があります。対応count_non_weekend_daysを作る

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 
$$; 

は、後に簡単です。

1

これに最適な解決策は、カレンダーテーブルを使用することです。これは非常に便利で、2つの日付の間の就業日数のカウントや、2つの日付間の休日の数のカウントなど、あらゆる面白いことを行うことができます。

この表には、通常、20年間、よく知られている休日の日付が適切にタグ付けされています。休日が移行する場合、休日として日をマークするために、テーブルをしばらく維持します。 More info hereおよびhere。これはMS SQL Serverを使用しますが、簡単に移植されます。

0

2つの日付の間の特定の日:

-- 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 
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 

第一および第二日は月曜日であり、我々は2つの土曜日とそれらの間の2回の日曜日を持っているので、この選択は4を返す必要があります。

さて、は(週末なし)のみ営業日を返すために、あなたがをしたいと、以下の例のように、単に、減算を行います。

SELECT (date '2017-09-25' - date '2017-09-11') - <YourSchemaName>.count_full_weekend_days('2017-09-11', '2017-09-25'); --> RES: 14 - 4 = 10 
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; 
関連する問題