3

postgresに2つのタイムスタンプがある場合、土曜日と日曜日全体をカウントせずに時間差を計算するにはどうすればよいですか?

また

特定の時間間隔での土曜日と日曜日の数をどのように数えますか?

4

8 に答える 8

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');
于 2009-04-15T12:37:39.737 に答える
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;
于 2015-12-08T22:16:02.737 に答える
1

これはあなたの質問の2番目の部分に答えるはずです:

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は簡単です。

于 2009-04-14T11:05:03.433 に答える
1

これに対する最善の解決策は、カレンダー テーブルを使用することです。これは信じられないほど便利で、2 つの日付間の稼働日数のカウントや 2 つの日付間の休日の数のカウントなど、あらゆる種類の興味深いことができます。

通常、このテーブルは事前に入力されます。たとえば、よく知られている祝日の日付が適切にタグ付けされた 20 年間などです。休日が変わる場合は、テーブルを時々維持して、その日を休日としてマークします。 詳細はこちらこちら。これは MS SQL Server を使用しますが、移植も簡単です。

于 2009-04-14T11:19:09.000 に答える
1

(days/7)*2 + 過去 (days%7) 日間の土/日の数。

于 2009-04-14T10:29:19.290 に答える
0

このブログ投稿が役立つかもしれません: http://www.depesz.com/index.php/2007/12/27/how-many-1sts-of-any-month-were-sundays-since-1901-01-01 //

于 2009-04-14T11:34:38.853 に答える
0

いつでも使用できるように関数を作成し、書く量を減らすことをお勧めします。)

上記のコードは、週末の日数 (Sat, Sun) をカウントして返す 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

1 日目と 2 日目が月曜日で、その間に 2 つの土曜日と 2 つの日曜日があるため、この select は 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
于 2015-09-29T17:47:56.473 に答える