トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

10-52 Interval型の総合計を求める

SQLパズル

テーブル
経過時間
--------
00.00001
22.22222
33.33333
44.44444

経過時間(interval day(3) TO second(5)型)の累計を
000日00時間00分00秒の形式で出力する

出力結果
経過時間            経過時間累計
------------------  -------------------
+00 00:00:00.86400  000日00時間00分01秒
+22 05:19:59.80800  022日05時間20分01秒
+33 07:59:59.71200  055日13時間20分00秒
+44 10:39:59.61600  100日00時間00分00秒


SQL

col 経過秒累計 for a20

--■■■秒を求めて計算する方法■■■
select RTrim(経過時間,'0') as 経過時間,
to_char(trunc(経過秒累計/24/60/60),'FM000') || '日' ||
to_char(trunc(mod(経過秒累計,24*60*60)/60/60),'FM00') || '時間' ||
to_char(trunc(mod(経過秒累計,60*60)/60),'FM00') || '分' ||
to_char(mod(経過秒累計,60),'FM00') || '秒' as 経過時間累計
from (select 経過時間,
      sum(extract(day    from 経過時間) *24*60*60 +
          extract(hour   from 経過時間) *60*60 +
          extract(minute from 経過時間) *60 +
          extract(second from 経過時間)) over(order by 経過時間) as 経過秒累計
from (
select cast(NumToDsInterval(00.00001,'day') as interval day(2) TO second(5)) as 経過時間 from dual
union select cast(NumToDsInterval(22.22222,'day') as interval day(2) TO second(5)) from dual
union select cast(NumToDsInterval(33.33333,'day') as interval day(2) TO second(5)) from dual
union select cast(NumToDsInterval(44.44444,'day') as interval day(2) TO second(5)) from dual))
order by 経過秒累計;

--■■■Interval型にcastして、正規表現で編集する方法(10g以降)■■■
select RTrim(経過時間,'0') as 経過時間,
RegExp_Replace(to_char(cast(NumToDsInterval(sum(sysdate+経過時間-sysdate) over(order by 経過時間)
               ,'day') as interval day(2) TO second(5))),
               '^[^0-9]*([0-9]+) ([0-9]+):([0-9]+):([0-9]+).*$','\1日\2時間\3分\4秒') as 経過秒累計
from (
select cast(NumToDsInterval(00.00001,'day') as interval day(2) TO second(5)) as 経過時間 from dual
union select cast(NumToDsInterval(22.22222,'day') as interval day(2) TO second(5)) from dual
union select cast(NumToDsInterval(33.33333,'day') as interval day(2) TO second(5)) from dual
union select cast(NumToDsInterval(44.44444,'day') as interval day(2) TO second(5)) from dual)
order by 経過秒累計;


解説

秒を求めて計算する方法では、
sum関数とextract関数を組み合わせて、秒の合計を求めて
trunc関数とmod関数を組み合わせて、経過時間を求めてます。

10-269 model句で期間型のsumを求める

How does one get the time difference between two date columns?(英語)