まず、CASEステートメントで物事を複雑にしすぎています。代わりに数学を使用できます。具体的には、Oracleが日付演算を行うときに数値を返すという事実です。さらに、日付に変換することで、算術演算を正しく実行できます。そのような大きなCASEステートメントでタイプミスをするのは簡単です。つまり、すべてが間違っているということです。このソリューションは、特定の30分だけでなく、1日のいつでも処理します。
次のようにテーブルを設定した場合:
create table times ( starttime varchar2(5), endtime varchar2(5) );
insert into times values ( '00:30','07:30');
insert into times values ( '16:00','19:00');
insert into times values ( '19:00','20:00');
次のクエリは、ほとんどの方法でそこに到達します。
SQL> select starttime
, endtime
, trunc( ( to_date(starttime,'hh24:mi')
- trunc(sysdate) ) * 48) + 1 as starttime_x
, trunc( ( to_date(endtime,'hh24:mi')
- trunc(sysdate) ) * 48) + 1 as endtime_x
from times;
START ENDTI STARTTIME_X ENDTIME_X
----- ----- ----------- ----------
00:30 07:30 1 16
16:00 19:00 33 39
19:00 20:00 39 41
次に、範囲内のすべての値のコンマ区切りリストを追加する必要があります。可能な限りこれを避けます...それはあなたにとってあまり役に立たないでしょう、そして表示するためだけに大丈夫でしょう。ただし、このデータはとの違いにstarttime_x
含まれendtime_x
ているため、どのようなメリットがあるのかわかりません。
ただし、それを実行する必要があると仮定すると、開始範囲と終了範囲の間に行を生成してから、それらを集約する必要があります。
SQL> with the_times as (
select starttime
, endtime
, trunc( ( to_date(starttime,'hh24:mi')
- trunc(sysdate) ) * 48) + 1 as starttime_x
, trunc( ( to_date(endtime,'hh24:mi')
- trunc(sysdate) ) * 48) + 1 as endtime_x
from times
)
, all_times as (
select level as t
from dual
connect by level <= 48
)
select starttime, endtime
, 'x' || starttime_x as starttime_x, 'x' || endtime_x as endtime_x
, listagg('x' || t, ', ') within group ( order by t ) as range
from ( select a.*, b.t
from the_times a
cross join all_times b
where b.t between a.starttime_x and a.endtime_x
)
group by starttime, endtime, 'x' || starttime_x, 'x' || endtime_x;
STARTTIME ENDTIME STA END RANGE
--------- ------- --- --- ---------------------------------------------------------------------------
00:30 07:30 x1 x16 x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16
16:00 19:00 x33 x39 x33, x34, x35, x36, x37, x38, x39
19:00 20:00 x39 x41 x39, x40, x41
ご覧のとおり、これは特にきれいではありません...
後で追加したことに注意してくださいx
。数字に任意の文字を追加することは、あなたがより困難にしなければならない算術を作るのに役立つだけです。最後にそれを追加することはこれを回避する方法です。