fc2ブログ

(元)社内SEの徒然なる日記

SQL(Oracle)で日差を計算する

■ 単純な日差

OracleSQLで差日数を計算してみます。テストデータは、以前に作成した日付一覧(SQL(Oracle)で土日と祝日をそれっぽく考慮した日付一覧の作成)を使います。

2017年8月9日と、日付一覧の抽出結果の差日数を取得するSQLです。
SELECT
TO_DATE(日付, 'YYYYMMDD') AS 日付
,TO_DATE('20170809', 'YYYYMMDD') -
TO_DATE(日付, 'YYYYMMDD') AS 日差
FROM
(

・・・ 前回のサンプルSQLの抽出結果 ・・・

)
ORDER BY 1


注意ですが、上記のSQL文に単純に前の記事のSQLを埋めてもダメです。あれはWITH句をつかっているので、WITH句の部分をSQL文の先頭に移さないと動きません。

取得値を日付型に変換して減算するだけで差日数が取得できます。Oracleは日付型で減算すると差日数になってくれるので楽で良いです。

■ 土日祝日考慮の日差

今度は、もうちょっと複雑に行きます。

開始日が 2017年7月14日(金)。終了日が 2017年7月20日(木)とすると、単純な日差は、6日になります。

ですが、土日祝を考慮すると、2017年7月15日(土)、2017年7月16日(日)、2017年7月17日(月、海の日)の 3日間が抜けるので、差日数は 3日になります。

この結果を取得するSQLはこんな感じです。
SELECT
COUNT(*) - 1 AS 日差
FROM
(

・・・ 前回のサンプルSQLの抽出結果 ・・・

)
WHERE
日付 BETWEEN '20170714' AND '20170720'
ORDER BY 1


日付一覧を指定範囲で抽出して、COUNT関数で件数を取得します。COUNT関数だと同一日が 1 となるので 1 減算します。

■ 複数の日付範囲を指定した日差

上記は日付範囲が1件だけでしたが、複数の日付範囲の場合も作ってみました。日付一覧にぶつけるデータ、DUAL表とUNION ALL を使用して作成しています。
SELECT
A.番号
,A.開始日
,A.終了日
,COUNT(*) - 1 AS 日差
FROM
(
SELECT
1 AS 番号
,TO_DATE('20170714', 'YYYYMMDD') AS 開始日
,TO_DATE('20170720', 'YYYYMMDD') AS 終了日
FROM DUAL

UNION ALL

SELECT
2 AS 番号
,TO_DATE('20170701', 'YYYYMMDD') AS 開始日
,TO_DATE('20170704', 'YYYYMMDD') AS 終了日
FROM DUAL

UNION ALL

SELECT
3 AS 番号
,TO_DATE('20170724', 'YYYYMMDD') AS 開始日
,TO_DATE('20170728', 'YYYYMMDD') AS 終了日
FROM DUAL
) A
,(

・・・ 前回のサンプルSQLの抽出結果 ・・・

) B
WHERE
A.開始日 <= B.日付(+)
AND A.終了日 >= B.日付(+)
GROUP BY
A.番号
,A.開始日
,A.終了日
ORDER BY A.番号



テストデータ(上記の内部テーブルA)の開始日、終了日の範囲で、日付一覧(上記の内部テーブルB)を抽出します。

後は、その単位でCOUNT関数を発行すれば良しです。

最新の記事:http://harikofu.blog.fc2.com/
投稿記事の一覧:http://harikofu.web.fc2.com/

--- blog end ---
スポンサードリンク

PageTop

コメント


管理者にだけ表示を許可する