あなたは、開始と終了ヶ月間の中間ヶ月と部分的な範囲のための完全な範囲で、複数ヶ月にあなたの日付の範囲を分割する必要があります。それを行う1つの方法はrecursive subquery factoring
で
with rcte (req, start_dt, end_dt, period_start_dt, period_end_dt) as (
select req, start_dt, end_dt, start_dt,
case when trunc(end_dt, 'MM') = trunc(start_dt, 'MM') then end_dt
else last_day(start_dt) end
from your_table
union all
select req, start_dt, end_dt, add_months(trunc(period_start_dt, 'MM'), 1),
case when trunc(end_dt, 'MM') = add_months(trunc(period_start_dt, 'MM'), 1) then end_dt
else last_day(add_months(trunc(period_start_dt, 'MM'), 1)) end
from rcte
where trunc(end_dt, 'MM') > trunc(period_start_dt, 'MM')
)
select req, start_dt, end_dt, period_start_dt, period_end_dt,
period_end_dt - period_start_dt + 1 as delay,
extract(month from period_start_dt) as mm
from rcte
order by req, period_start_dt, period_end_dt;
REQ START_DT END_DT PERIOD_STA PERIOD_END DELAY MM
---------- ---------- ---------- ---------- ---------- ---------- ----------
1 2017-01-02 2017-03-05 2017-01-02 2017-01-31 30 1
1 2017-01-02 2017-03-05 2017-02-01 2017-02-28 28 2
1 2017-01-02 2017-03-05 2017-03-01 2017-03-05 5 3
2 2017-05-02 2017-07-06 2017-05-02 2017-05-31 30 5
2 2017-05-02 2017-07-06 2017-06-01 2017-06-30 30 6
2 2017-05-02 2017-07-06 2017-07-01 2017-07-06 6 7
で再帰CTEは、あなたのテーブルから初期データを取得するアンカー部材を有し、第1の期間の開始と終了を計算します。期間開始は元の範囲開始日です。期間終了は範囲終了日(同じ月の場合)またはその月の終わりです。
再帰メンバは、アンカーからの値を使用し、次の月の冒頭に開始し、元の範囲の終了日またはその月の終わりに終了する新しい期間を生成します。
期間の開始日と終了日を取得したら、通常の日付減算を使用して差額を計算するのは簡単です。
少し単純計算のため、(あなたがそれらをしたくない場合だけで、最終的な選択リストから削除し、私は試してみて、それが少し明確にするために、出力期間の開始/終了日を残してきました。)期間の開始/終了日:
with rcte (req, start_dt, end_dt, period_start_dt, period_end_dt) as (
select req, start_dt, end_dt, start_dt, least(end_dt, last_day(start_dt))
from your_table
union all
select req, start_dt, end_dt, add_months(trunc(period_start_dt, 'MM'), 1),
least(end_dt, last_day(add_months(trunc(period_start_dt, 'MM'), 1)))
from rcte
where trunc(end_dt, 'MM') > trunc(period_start_dt, 'MM')
)
select req, start_dt, end_dt,
period_end_dt - period_start_dt + 1 as delay,
extract(month from period_start_dt) as mm
from rcte
order by req, period_start_dt, period_end_dt;
REQ START_DT END_DT DELAY MM
---------- ---------- ---------- ---------- ----------
1 2017-01-02 2017-03-05 30 1
1 2017-01-02 2017-03-05 28 2
1 2017-01-02 2017-03-05 5 3
2 2017-05-02 2017-07-06 30 5
2 2017-05-02 2017-07-06 30 6
2 2017-05-02 2017-07-06 6 7
何ロジックあなたはその結果を取得するために使用していますか?あなたはそれを達成しようとしましたか? –
シンプルな日数の場合は、word:date1 - date2を指定します。月の違いを得るために、MONTHS_BETWEEN関数があります。 – Alex
遅延とMMの列の日付と値の間に関係は実際には分かりません。最後の3行は正確に同じ日付を持ち、遅延値とMM値が異なります。あなたの論理は何ですか? –