トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
10-342 重複する間隔をまとめて、その合計を求める
SQLパズル
LoginTable
dayC LoginTime LogoutTime
---------- --------- ----------
2010-11-21 06:30:00 07:30:00
2010-11-21 06:40:00 07:20:00
2010-11-21 06:50:00 07:50:00
2010-11-21 07:30:00 08:30:00
2010-11-21 09:30:00 10:30:00
2010-11-21 13:50:00 14:20:00
2010-11-21 14:10:00 14:40:00
LoginTimeからLogoutTimeまでの重複する間隔をまとめて、その合計を求める。
06:30:00から08:30:00までと
09:30:00から10:30:00までと
13:50:00から14:40:00までなので、3時間50分となります。
出力結果
TimeSpent
-----------------------------
+000000000 03:50:00.000000000
データ作成スクリプト
create table LoginTable(dayC,LoginTime,LogoutTime) as
select '2010-11-21','06:30:00','07:30:00' from dual union all
select '2010-11-21','06:40:00','07:20:00' from dual union all
select '2010-11-21','06:50:00','07:50:00' from dual union all
select '2010-11-21','07:30:00','08:30:00' from dual union all
select '2010-11-21','09:30:00','10:30:00' from dual union all
select '2010-11-21','13:50:00','14:20:00' from dual union all
select '2010-11-21','14:10:00','14:40:00' from dual;
SQL
select NumToDsInterVal(sum(max(LogoutTime)-min(LoginTime)),'day') as time_spent
from (select LoginTime,LogoutTime,
sum(willSum) over(order by LoginTime) as GID
from (select LoginTime,LogoutTime,
case when LoginTime
<= max(LogoutTime)
over(order by LoginTime
range between UnBounded preceding
and InterVal '1' second preceding)
then 0 else 1 end as willSum
from (select
to_date(dayC || LoginTime ,'yyyy-mm-ddhh24:mi:ss') as LoginTime,
to_date(dayC || LogoutTime,'yyyy-mm-ddhh24:mi:ss') as LogoutTime
from LoginTable)))
group by GID;
解説
date型 - date型の結果のNumber型を、
NumToDsInterVal関数の引数に使用し、
InterVal型で期間の合計を求めてます。
期間をまとめるロジックでは、検索case式と分析関数のrange指定を組み合わせてます。
OracleSQLパズル 9-3 開始日と終了日をまとめる
マニュアル --- NumToDsInterVal