Oracleにおける営業日テーブルを作成する方法です。方法は色々あると思いますが、シンプルな方法でデータを投入したいと思います。
二段階のステップで営業日テーブルを作成
それほど特殊なことは行いません。と言っても、データ作成時に365日分(閏年なら366日分)のINSERT文を作るのはミスになる可能性があるため、
- 平日と休日で分けて全日登録
- 土日祝のうち、営業日に該当する日を更新する
という二段階のステップを踏みます。
営業日テーブルのデータを作成
とりあえず営業日テーブルのサンプルです。
--営業日テーブル作成 CREATE TABLE Business_Calendar_Table ( Calendar_Date DATE PRIMARY KEY, Business_Day_Flg CHAR(1) );
特に何の変哲もない、日付と営業日フラグだけのシンプルなテーブルです。
平日と休日で分けて全日登録
ではデータにいきましょう。まず、365日分(閏年なら366日分)のデータを登録します。この時に、平日を営業日として登録し、休日は営業日のフラグを0にします。サンプルクエリはこちら。
-- 平日を営業日として設定 INSERT INTO Business_Calendar_Table (Calendar_Date, Business_Day_Flg) SELECT TO_DATE('2024-01-01', 'YYYY-MM-DD') + LEVEL - 1, CASE WHEN TO_CHAR(TO_DATE('2024-01-01', 'YYYY-MM-DD') + LEVEL - 1, 'D') BETWEEN 2 AND 6 THEN '1' ELSE '0' END FROM dual CONNECT BY TO_DATE('2024-01-01', 'YYYY-MM-DD') + LEVEL - 1 <= TO_DATE('2024-12-31', 'YYYY-MM-DD'); -- 土曜日と日曜日を非営業日として設定 UPDATE Business_Calendar_Table SET Business_Day_Flg = '0' WHERE TO_CHAR(Calendar_Date, 'D') IN (1, 7); --1は日曜日、7は土曜日
これでとりあえず、平日が営業日となるデータが揃いました。
ちょいちょい出て来る「LEVEL」は、LEVEL疑似列というもので、階層的なクエリを実行する際に使えるので、覚えておいて損はないです。
また、最後に「CONNECT BY」としていますが、これは、CONNECT BY句です。再帰条件とするために使用しています。普段、我々はWHERE句を無意識に使用していますが、WHERE句は終了条件です。つまり親戚みたいなものです。WHERE句はそこで諦めて試合終了してしまいますが、CONNECT BY句は再帰条件なので、条件が成立している場合は、諦めずに木構造を作り続けてくれます。
今回の場合、
CONNECT BY TO_DATE('2024-01-01', 'YYYY-MM-DD') + LEVEL - 1 <= TO_DATE('2024-12-31', 'YYYY-MM-DD');
としているので、2024年1月1日から2024年12月31日まで頑張って再帰を続けてくれます。
また、土曜日と日曜日を非営業日として設定しているところでは、
TO_CHAR(Calendar_Date, 'D') IN (1, 7);
としています。Date型の値に対して、TO_CHARを使用することで、曜日を取得することが出来ます。1が日曜日で開始値、7が土曜日で終了値です。
試しに、このクエリを実行してみてください。
SELECT TO_CHAR(SYSDATE, 'D') FROM dual;
SYSDATEを指定しているので、実行した曜日に応じて数字が返って来ます。「SYSDATE -数字」で過去に遡ることが出来ます。
祝日を更新
先ほどのクエリはあくまでも土曜日・日曜日に対して営業日フラグを0にしただけなので、祝日に対応していません。なので、祝日に該当する日に対して営業日フラグを0にする必要があります。
というわけで、作りました。
-- 祝日を非営業日として設定(2024年) UPDATE Business_Calendar_Table SET Business_Day_Flg = '0' WHERE Calendar_Date IN ( TO_DATE('2024/1/1', 'YYYY/MM/DD'), TO_DATE('2024/1/8', 'YYYY/MM/DD'), TO_DATE('2024/2/11', 'YYYY/MM/DD'), TO_DATE('2024/2/12', 'YYYY/MM/DD'), TO_DATE('2024/2/23', 'YYYY/MM/DD'), TO_DATE('2024/3/20', 'YYYY/MM/DD'), TO_DATE('2024/4/29', 'YYYY/MM/DD'), TO_DATE('2024/5/3', 'YYYY/MM/DD'), TO_DATE('2024/5/4', 'YYYY/MM/DD'), TO_DATE('2024/5/5', 'YYYY/MM/DD'), TO_DATE('2024/5/6', 'YYYY/MM/DD'), TO_DATE('2024/7/15', 'YYYY/MM/DD'), TO_DATE('2024/8/11', 'YYYY/MM/DD'), TO_DATE('2024/8/12', 'YYYY/MM/DD'), TO_DATE('2024/9/16', 'YYYY/MM/DD'), TO_DATE('2024/9/22', 'YYYY/MM/DD'), TO_DATE('2024/9/23', 'YYYY/MM/DD'), TO_DATE('2024/10/14', 'YYYY/MM/DD'), TO_DATE('2024/11/3', 'YYYY/MM/DD'), TO_DATE('2024/11/4', 'YYYY/MM/DD'), TO_DATE('2024/11/23', 'YYYY/MM/DD') );
これを実行すると、祝日も非営業日にすることが出来ます。
土日祝のうち、営業日に該当する日を更新する
これは各所属組織や会社に合わせて欲しいのですが、「この日(土曜日)だけは営業日なんです」みたいな会社の場合は、該当する日の営業日フラグを1にするUPDATE文を組んで下さい。
逆に、「平日だけど創設記念日で休み」の場合は、該当する日の営業日フラグを0にするUPDATE文を組んで下さい。
そもそも、土日が休みじゃない会社なのですが…
考え方は一緒で、例えば、火曜日と水曜日が休みの会社の場合は、以下の様にしてあげれば大丈夫です。
UPDATE Business_Calendar_Table SET Business_Day_Flg = '0' WHERE TO_CHAR(Calendar_Date, 'D') IN (3, 4); --火曜日と水曜日が休み
TO_CHAR(Calendar_Date, ‘D’)で返って来る値に対して営業日フラグを0とするUPDATE文なので、各会社の営業日に応じて変更して下さい。