お世話になっております
日付範囲で単価を取得するテーブルを作っており、
一時的に変わる時だけ終了日を入れて範囲を決めています
(8/5~8/10 & 8/6~8/11のような複数で日付が被る形はありません)
例
開始日 終了日 単価
2021/08/01 Null 150
2021/08/05 2021/08/10 120
2021/08/20 Null 140
このようなデータで日付を指定した際に
指定日付 2021/08/01 ~ 2021/08/04 基準開始日 2021/08/01 単価150
指定日付 2021/08/05 ~ 2021/08/10 基準開始日 2021/08/05 単価120
指定日付 2021/08/11 ~ 2021/08/19 基準開始日 2021/08/01 単価150
指定日付 2021/08/20 ~ 基準開始日 2021/08/20 単価140
と基準開始日と単価が返ってくるようにしたいのです
現状は最初に
指定日付>=開始日 AND ISNULL(終了日)=FALSE で抽出後
指定日付<=終了日であればその期間の開始日とその時の単価を取得
そうでなければ指定日付>=開始日 AND ISNULL(終了日)=TRUE の中でMAXの開始日とその時の単位を取得 という形を
取っているのですがこれ以上簡単にできる方法はありませんでしょうか?
これ、結果は一意じゃないですよね。2レコード以上HITしたらどうしてるんですか?
このデータ形式でテーブルを作らないのは何故なんでしょう?
2レコード以上は範囲入力側の制御の時点で入れられない形にしています
>(8/5~8/10 & 8/6~8/11のような複数で日付が被る形はありません)
あくまで終了日付が入るのは期間限定の臨時の時だけで基本的には開始日で単価を制御するようになっており、
単価情報を入力する側が期間限定明け後のデータ入力(ここでは8/11~8/19)を意識しなくてもいい形にしたいというものです
例えば
のようなデータの時、
指定日=2021/08/15
の場合すると
と、2レコードHITします
これは、つまり、このようなレコードは存在しないということでしょうか?だとすると、終了日に値の存在が許されるレコードは1つだけという歪なテーブル構造なんでしょうか?
質問の解自体はhatenaさんの回答の通りでしょう。ただ、手順や処理時間で見た簡略化は見込めないと思います。この観点から言えば
ないです
しかしながら、データ構造の観点から言えば、「一時的に変わる時」のデータは単純に追加するだけで済むというメリットができ、データ管理面での単純化なら見込めます
さらに言えば、既に指摘している通り、なぜ最終的なデータ構造でテーブルを作らないのか?という話になります。データ構造が単純で、データの取得もシンプルです
単純=「簡単」とは限らないですが、テーブル構造からはわからない独自ルールを運用するよりはよほど「簡単」でしょう。
本当の主題はこれですよね?
ならば、職人芸のようなテーブル構造・データ取得を考えるよりも単純に「期間限定明け後のデータ入力(ここでは8/11~8/19)を」自動化したいと考えるべきでしょう
hirotonさんの提示したテーブルのような形にしない限りは、簡単にはならないと思います。
どのようなUIなのか不明なので、
フォーム上に「日付」と「単価」というテキストボックスがあると仮定すると、
下記のようなコードで期待する結果にはなります。
hirotonさんの提示したテーブルなら、下記の1行のコードで済みます。
私個人は、hirotonさんやhatenaさんと同じく
ソリューションとしては 圧倒的に
{ テーブルデータの保有形式を変更 } >>> { トリッキーな SQL または VBA }
という見解です。
ただ Access の一般機能で「 実現可能 」な ご要望であることも事実ですから
実用性とパフォーマンスは度外視で、SQL( クエリ )のサンプル を載せておきます。
( ※ 今回の投稿はテーブル定義とデータ例のみ )
なお、( 何らかの )日付範囲の抽出条件を満たした後のデータが
「 例 」の3行であるとするなら
「 指定日付 」に該当するような パラメータなりリテラル値は
開始日フィールドに指定された可能性が高いと推測し、
私の回答( SQL )では、現状のテーブルデータに影響を与えない抽出条件として
を指定しています。
■テーブル: 単価マスタ
■テーブル: T_num
( T_num テーブル の num には 0 ~ 9 までの数値を入力 )
( 続き )
# 最初は SQLの一筆書きを投稿しようとしたところ
# 160行の記述が長すぎて投稿不可であったことと
# サブクエリのネストが深くて、記述が複雑怪奇になったため、
# 構造別にクエリを複数( 計7つ )作るという回答に切り替えました。
まぁ...個々の記述が短いと 最終結果が出るまでの工程も分かりやすいでしょう。
( クエリを作る順番も、掲載した順と同じになります )
q_base
q_ymd
q_ymdlist
( 続き )
q_fromto
q_highlow
q_union
q_result
ありがとうございます
クエリで日付から単価や開始日を呼び出したりする形で使いたかったので
hatenaさんのコードをもとに標準モジュール(日付を入数化)にする形で対応できました