質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

3回答

509閲覧

【SQL】【select】当日から次回長期休みの開始日と終了日の取得

退会済みユーザー

退会済みユーザー

総合スコア0

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

1クリップ

投稿2019/01/22 06:03

編集2022/01/12 10:55

前提・実現したいこと

下記のようなテーブルがあり
検索した当日から次回の長期休暇の開始日と終了日を取得するselect文を作りたいのですが
よい取得方法がありましたらご教授ください。

カレンダーテーブル

ID休日区分date
12019/7/19
2夏休み2019/7/20
3夏休み2019/7/21
------
a夏休み2019/8/30
a+1夏休み2019/8/31
a+22019/9/1
------
b2019/12/19
b+1冬休み2019/12/20
b+2冬休み2019/12/21
------
c冬休み2020/1/6
c+1冬休み2020/1/7
c+22020/1/8
------
d2020/3/27
d+1春休み2020/3/28
------
e春休み2020/4/6
e+12020/4/7
------
f2020/7/20
f+1夏休み2020/7/21
------
g夏休み2020/8/31
g+12020/9/1

例1:2019/4/1に検索した場合
夏休み開始日2019/7/20
夏休み終了日2019/8/31
冬休み開始日2019/12/20
冬休み終了日2020/1/7
春休み開始日2020/3/27
春休み終了日2020/4/6

例1:2019/8/1に検索した場合
冬休み開始日2019/12/20
冬休み終了日2020/1/7
春休み開始日2020/3/27
春休み終了日2020/4/6
夏休み開始日2020/7/20
夏休み終了日2020/8/31

試したこと

各休みに対してSQLを実行する

検索日をsysdateより参照しその年の夏休み開始日終了日を検索する。(dateで期間指定,IDのmax,minを取る)
この時検索日が開始日を過ぎていた場合は、翌年の夏休み開始日終了日を取得する。

検索日をsysdateより参照しその年の春休み開始日終了日を検索する。(dateで期間指定,IDのmax,minを取る)
この時検索日が開始日を過ぎていた場合は、翌年の春休み開始日終了日を取得する。

検索日をsysdateより参照しその年の12月から翌年2月までの期間を指定して冬休みを取る(dateで期間指定,IDのmax,minを取る)
この時検索日が開始日を過ぎていた場合は、翌年の冬休み開始日終了日を取得する。

補足情報(FW/ツールのバージョンなど)

DBの種類:oracle

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/01/22 06:11

>DBの種類:oracle であればタグに追加してください。
kunai

2019/01/22 06:19 編集

テーブルがみにくいので、| |で囲ってテーブルレイアウトで表示できるようにしていただけませんか。 あと、休日区分が書かれていないものがありますが、何をもって長期休暇データと判断すればいいのでしょうか。 また、長期休暇の開始か終了かは判断するフラグ等はないのでしょうか。
退会済みユーザー

退会済みユーザー

2019/01/22 07:30

mts10806様 ご指摘ありがとうございます、タグに追加いたしました。 kunai様 ご指摘ありがとうございます、テーブルレイアウトを変更いたしました。 >>休日区分が書かれていないものがありますが、何をもって長期休暇データと判断すればいいのでしょうか。 休日区分に『春休み』『夏休み』『冬休み』が記載されているレコードが長期休暇の日付になります。 空欄は長期休暇以外の日付です。 >>長期休暇の開始か終了かは判断するフラグ等はないのでしょうか。 残念ながらテーブルにフラグ等が無いため、それ以外で判断するより無い状況です。
Orlofsky

2019/01/22 09:21

質問のテーブル定義はCREATE TABLE文とINSERT文で載せた方が適切なコメントが付き易いです。
退会済みユーザー

退会済みユーザー

2019/01/23 02:37

Orlofsky様 ご助言ありがとうございます、参考にさせていただきます。
Orlofsky

2019/01/23 03:25

参考ね。質問を修正する気はない、と。
guest

回答3

0

年度は日付から-3か月したものの年で表わせますので、それをグルーピングに含めます。

SQL

1with range_calender as ( 2 select EXTRACT(year from ADD_MONTHS(date, -3)) as fiscal_Year 3 , 休日区分, min(date) as start_date, max(date) as end_date 4 from calender 5 group by EXTRACT(year from ADD_MONTHS(date, -3)) , 休日区分 6) 7select * from range_calender 8where start_date=(select min(start_date) from range_calender where start_date > [指定の日])

投稿2019/01/26 16:00

sazi

総合スコア25138

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ご指摘・ご回答ありがとうございました。
現行の対応として下記のSQLで必要データを取得しようと思います。

必要なデータを取得するSQLを1本にまとめられましたが、
データ取得後に当日より後の物を判断する処理は残っている状況です。

SQL

1WITH THIS_YEAR AS ( 2 3SELECT 4 MIN(CASE WHEN 休日区分 = '春休み' THEN date ELSE NULL END) AS SPRING_MIN_DATE --春休み開始日 5 ,MAX(CASE WHEN 休日区分 = '春休み' THEN date ELSE NULL END) AS SPRING_MAX_DATE --春休み終了日 6 ,MIN(CASE WHEN 休日区分 = '夏休み' THEN date ELSE NULL END) AS SUMMAR_MIN_DATE --夏休み開始日 7 ,MAX(CASE WHEN 休日区分 = '夏休み' THEN date ELSE NULL END) AS SUMMAR_MAX_DATE --夏休み終了日 8 ,MIN(CASE WHEN 休日区分 = '冬休み' THEN date ELSE NULL END) AS WINTER_MIN_DATE --冬休み開始日 9 ,MAX(CASE WHEN 休日区分 = '冬休み' THEN date ELSE NULL END) AS WINTER_MAX_DATE --冬休み終了日 10FROM 11 calender 12WHERE 13 date BETWEEN TO_DATE(CONCAT(TO_CHAR(SYSDATE, 'YYYY'),'/03/01')) AND TO_DATE(CONCAT(TO_CHAR(ADD_MONTHS(SYSDATE,12), 'YYYY'),'/03/01')) --今年3月~翌年3月 14GROUP BY 休日区分 15 16), NEXT_YEAR AS ( 17 18SELECT 19 MIN(CASE WHEN 休日区分 = '春休み' THEN date ELSE NULL END) AS SPRING_MIN_DATE --春休み開始日 20 ,MAX(CASE WHEN 休日区分 = '春休み' THEN date ELSE NULL END) AS SPRING_MAX_DATE --春休み終了日 21 ,MIN(CASE WHEN 休日区分 = '夏休み' THEN date ELSE NULL END) AS SUMMAR_MIN_DATE --夏休み開始日 22 ,MAX(CASE WHEN 休日区分 = '夏休み' THEN date ELSE NULL END) AS SUMMAR_MAX_DATE --夏休み終了日 23 ,MIN(CASE WHEN 休日区分 = '冬休み' THEN date ELSE NULL END) AS WINTER_MIN_DATE --冬休み開始日 24 ,MAX(CASE WHEN 休日区分 = '冬休み' THEN date ELSE NULL END) AS WINTER_MAX_DATE --冬休み終了日 25FROM 26 calender 27WHERE 28 date BETWEEN TO_DATE(CONCAT(TO_CHAR(ADD_MONTHS(SYSDATE,12), 'YYYY'),'/03/01')) AND TO_DATE(CONCAT(TO_CHAR(ADD_MONTHS(SYSDATE,24), 'YYYY'),'/03/01')) --翌年3月~翌々年3月 29GROUP BY 休日区分 30 31) 32 33SELECT * FROM THIS_YEAR 34UNION ALL 35SELECT * FROM NEXT_YEAR

投稿2019/01/23 02:55

編集2019/01/23 03:02
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

SQL

1SELECT MIN(date) AS start_date, MAX(date) AS finish_date, 休日区分, DATE_FORMAT(date, '%Y') AS year 2FROM calender 3GROUP BY 休日区分, year;

こんな感じでしょうか?

追記 (2019/01/23)

SQL

1SELECT MIN(date) AS start_date, 2 MAX(date) AS finish_date, 3 休日区分, 4 CASE 5 WHEN DATE_FORMAT(date, '%M') <= 3 6 THEN DATE_FORMAT(date, '%Y')+1 // 1~3月の場合に+1して年度の値にする 7 ELSE DATE_FORMAT(date, '%Y') 8 END AS year_period 9FROM calender 10GROUP BY 休日区分, year_period;

年度の処理、これでよいのでは??
(春休みが年度を跨いでいる場合は春休みが確実に終了している日(4/20とか)より前か後かで場合分けすればよいかと)

投稿2019/01/22 09:28

編集2019/01/23 03:54
takg

総合スコア125

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takg

2019/01/22 09:35

あ、冬休みは年をまたぐのでダメですね。 yearの代わりに、年度を表すカラムを作ってGROUP BYするとか?
退会済みユーザー

退会済みユーザー

2019/01/23 02:35

takg様 回答ありがとうございます。 年毎に出すと冬休みが切れてしまうので、悩みどころです。 すでにデータが入っている者なので年度カラムを再度追加するのは難しい状況です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問