土日、祝祭日をカウントしないで、経過日数から処理を行いたい。
休日テーブルのようなものを作って、LEFTJOINして加工
のようなことをやっていたが、
DBなくても動くものが欲しかったので、調べてみたオボエガキ。
範囲を絞る方法として、
次のように使う
select 【id】 from 【table名】
where (to_timestamp(to_char(now(),'YYYY-MM-DD'),'YYYY-MM-DD') -
(to_timestamp(to_char(【table名】.【受付日】,'9999-99-99'),'YYYY-MM-DD'))) > interval '5 days'
and
(SELECT count(*) FROM generate_series(to_timestamp(to_char(【table名】.【受付日】,'9999-99-99'),'YYYY-MM-DD'),
to_timestamp(to_char(now(),'YYYY-MM-DD'),'YYYY-MM-DD')-interval '1 day',
interval '1 day') the_day
WHERE (extract('ISODOW' FROM the_day) < 6
and not(EXTRACT(MONTH FROM the_day) * 100
+ EXTRACT(DAY FROM the_day)
IN (101, 113, 211, 223, 224, 320, 429, 503, 504, 505, 506, 723, 724, 810, 921, 922, 1103, 1123) ) ) ) >4
idが 【table名】.【受付日】から5日以上経過(当日含まないので中4日)
なお、条件として、【table名】.【受付日】がint2(8)の為、DATE型に変換している。
解説
副問い合わせをしているのだが、
(SELECT count(*) FROM
generate_series(to_timestamp(to_char(【table名】.【受付日】,'9999-99-99'),'YYYY-MM-DD'),
to_timestamp(to_char(now(),'YYYY-MM-DD'),'YYYY-MM-DD')-interval
'1 day',
interval '1 day') the_day
WHERE (extract('ISODOW' FROM
the_day) < 6
and not(EXTRACT(MONTH FROM the_day) * 100
+ EXTRACT(DAY
FROM the_day)
IN (101, 113, 211, 223, 224, 320, 429, 503, 504, 505, 506, 723, 724, 810, 921, 922, 1103, 1123) ) ) ) >4
generate_series という集合を返す関数を使って、カウントが中4日となる様に制御している。
generate_series
(
to_timestamp(to_char(【table名】.【受付日】,'9999-99-99'),'YYYY-MM-DD'),
to_timestamp(to_char(now(),'YYYY-MM-DD'),'YYYY-MM-DD')-interval
'1 day',
interval '1 day'
) the_day
始まり,終わり,間隔 と記載している。
終わりの中で -interval
'1 day' としているのは、当日を入れたくないため。
WHERE
(
extract('ISODOW' FROM
the_day) < 6
and not
(
EXTRACT(MONTH FROM the_day) * 100
+
EXTRACT(DAY
FROM the_day)
IN
(101, 113, 211, 223, 224, 320, 429, 503, 504, 505, 506, 723, 724, 810, 921, 922, 1103, 1123)
)
extract('ISODOW' FROM
the_day) < 6 ISODOWは6が土曜、7が日曜となる。
(DOWだと0が日曜、6が土曜)
and not 以下の括りで、国民の休日をカウント対象から除外させている。
EXTRACT(MONTH FROM the_day) * 100
+
EXTRACT(DAY
FROM the_day)
で月を100倍し、日と足す。
これを 副問い合わせのIN関数
(左側の式の結果が右側の式のどれかと等しい場合、結果は「真」を返す)
を用いて、その日付だった場合は、2重否定となり、カウントされない。
固定日以外の春分の日なんかは、国立天文台の算定式で括ってあげればいいんだが、
このところ、天皇即位やオリンピックで変則が多いので、調べて直接日付を書いたほうが
よさそう。
春分の計算
(EXTRACT(MONTH FROM date) = 3
AND EXTRACT(DAY FROM date) = FLOOR(20.8431
+ 0.242194 * (EXTRACT(YEAR FROM date) - 1980))
- FLOOR((EXTRACT(YEAR FROM date) - 1980) / 4))
and not でそれぞれ括れば、除外できるが
and not が直ぐに思いつかなかった・・・。