タイガーラック クリエイティブブログ
2024
October
17

PostgreSQLで翌営業日を取得する方法

業務を行う上で、特定の日付の次の営業日を取得したいということはあるかと思います。
土日祝を含んで計算しようとすると厄介ですが、PostgreSQLでも出力が可能なので紹介したいと思います。

※この記事はPostgreSQL 13.5 で動作確認してます。

祝日に関しては祝日マスタのような会社指定の休業日を持ってるテーブルが必要になります。

t_holiday
holiday	holiday_name
2023-03-21	春分の日
2023-05-03	憲法記念日
2023-05-04	みどりの日
2023-05-05	こどもの日

SQLはこちら

  SELECT 
    lag(SEQDAY ,-(1 + cnt)) OVER(ORDER BY SEQDAY)  as NEXT_DAY
  FROM 
  (SELECT 
      CAST(A AS DATE) SEQDAY
   FROM
      (SELECT GENERATE_SERIES('2023/05/01'::date, '2023/05/01'::date + 15, '1 day') AS A) DAYS
  )DAYS
    LEFT JOIN t_holiday KYU
      ON DAYS.SEQDAY = KYU.holiday 
  CROSS JOIN 
    --指定日が土日祝かチェック
    (SELECT CASE WHEN COUNT(*) = 0 THEN -1 ELSE 0 END cnt 
    FROM 
      (SELECT 
          CAST(A AS DATE) SEQDAY
       FROM
          (SELECT GENERATE_SERIES('2023/05/01'::date,'2023/05/01'::date + 15, '1 day') AS A) DAYS
      )DAYS
        LEFT JOIN t_holiday KYU
          ON DAYS.SEQDAY = KYU.holiday 
      WHERE
          EXTRACT(DOW FROM CAST(DAYS.SEQDAY AS DATE)) NOT IN (6,0)
          AND holiday IS NULL
          AND SEQDAY = '2023/05/01' 
    )b
  WHERE
    EXTRACT(DOW FROM CAST(DAYS.SEQDAY AS DATE)) NOT IN (6,0)
    AND holiday IS NULL
  limit 1;

上のSQLは5月1日の次の営業日を取得したいので指定日を文字列で2023年5月1日を入力してます。

指定日が土日祝の場合は参照するレコードが変わるのでCROSS JOINで土日祝のチェックを行っています。

functionにする場合はこちら

翌営業日の取得に関しては何回も取得することになると思うのでその場合はファンクションにすると便利になります。

CREATE OR REPLACE FUNCTION "public"."NEXT_DAY"("datdate" date, "nissu" int4)
  RETURNS "pg_catalog"."date" AS $BODY$
BEGIN
  --平日か土日祝で指定日が異なる
  return lag(SEQDAY ,-(Nissu + cnt)) OVER(ORDER BY SEQDAY)  as 次営業日
  FROM 
  (SELECT 
      CAST(A AS DATE) SEQDAY
   FROM
      (SELECT GENERATE_SERIES(datDate, datDate + 15, '1 day') AS A) DAYS
  )DAYS
    LEFT JOIN t_holiday KYU
      ON DAYS.SEQDAY = KYU.holiday 
  CROSS JOIN 
    --指定日が土日祝かチェック
    (SELECT CASE WHEN COUNT(*) = 0 THEN -1 ELSE 0 END cnt 
    FROM 
      (SELECT 
          CAST(A AS DATE) SEQDAY
       FROM
          (SELECT GENERATE_SERIES(datDate,datDate + 15, '1 day') AS A) DAYS
      )DAYS
        LEFT JOIN t_holiday KYU
          ON DAYS.SEQDAY = KYU.日付 
      WHERE
          EXTRACT(DOW FROM CAST(DAYS.SEQDAY AS DATE)) NOT IN (6,0)
          AND holiday IS NULL
          AND SEQDAY = datDate 
    )b
  WHERE
    EXTRACT(DOW FROM CAST(DAYS.SEQDAY AS DATE)) NOT IN (6,0)
    AND holiday IS NULL
  limit 1;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100

実行SQL

SELECT NEXT_DAY('2023/05/02',1)

結果
2023/05/08

第一引数に開始日付、第二引数に何日後の営業日を取得するかの数値を指定。

上のファンクションは1営業日を取ってくる前提なので10日後の営業日を取得したい!

となるとGENERATE_SERIESの終了日付を15日からもっと伸ばす必要があります。

上のSQLから修正を加えれば前営業日や土日以外の休みにも対応できます。

このカテゴリの最新記事

関連記事

SHOP LIST

タイガーラック株式会社

〒577-0056
大阪府東大阪市長堂1-3-14 TOKUYASU Bld.