您好我收到的Oracle Query返回:
SensorKey StartTime EndTime
45 2012.10.17 08:31 2012.10.17 10:21
45 2012.10.17 10:26 2012.10.17 10:51
45 2012.10.17 12:21 2012.10.17 12:26
45 2012.10.17 12:41 2012.10.17 13:41
45 2012.10.17 13:51 2012.10.17 14:46
45 2012.10.17 15:11 2012.10.17 15:16
45 2012.10.17 15:46 2012.10.17 16:21
45 2012.10.17 18:51 2012.10.17 18:56
45 2012.10.17 19:11 2012.10.17 19:56
45 2012.10.17 20:26 2012.10.17 21:11
45 2012.10.17 22:16 2012.10.17 22:21
45 2012.10.17 22:26 2012.10.17 22:56
45 2012.10.17 23:36 2012.10.18 01:46
45 2012.10.18 02:16 2012.10.18 02:56
45 2012.10.18 03:31 2012.10.18 15:06
45 2012.10.18 15:31 2012.10.18 16:41
45 2012.10.18 17:41 2012.10.18 18:06
45 2012.10.18 19:16 2012.10.18 19:26
45 2012.10.18 19:36 2012.10.18 19:41
45 2012.10.18 20:51 2012.10.18 23:16
45 2012.10.19 00:01 2012.10.19 00:51
我需要获得所有数据的结果。第一行示例:
SensorKey StartTime EndTime
45 2012.10.17 08:31 2012.10.17 10:21
像这样,依此类推其他行:
TimeKey Hour SensorKey Duration StartTime EndTime
20121017 8 45 29 2012.10.17 08:31 2012.10.17 10:21
20121017 9 45 60 2012.10.17 08:31 2012.10.17 10:21
20121017 10 45 21 2012.10.17 08:31 2012.10.17 10:21
规则:
复制一行多次小时重叠,例如第一行重叠8,9,10小时。
Timekey
=来自StartTime
的日期格式YYYYMMDD
Hour
=来自StartTime
的小时格式为H
24H
Duration
小时持续时间(分钟)。
如果一小时内有多行,则必须对两个第一行进行分组示例:
我
TimeKey Hour SensorKey Duration StartTime EndTime
20121017 8 45 29 2012.10.17 08:31 2012.10.17 10:21
20121017 9 45 60 2012.10.17 08:31 2012.10.17 10:21
20121017 10 45 46 2012.10.17 08:31 2012.10.17 10:21
答案 0 :(得分:1)
对于Oracle,一种方法是Model子句(因为我们正在组成行,model子句可以为我们这样做)。
一些事情。你似乎只想要数据到分钟,所以使用日期与时间戳是有意义的。其次,我要避免在oracle的表中使用区分大小写的名称(在下面的查询中,我将您的数据别名化为非敏感的,以使其更容易编码:))SQL> with data as (select rownum id, "SensorKey" s_key, cast("StartTime" as date) s_time, cast("EndTime" as date) e_time,
2 ((trunc(cast("EndTime" as date) , 'hh24') -trunc(cast("StartTime" as date), 'hh24')) *24)+1 hours
3 from table1)
4 select to_char(block_start, 'yyyymmdd') "TimeKey",
5 thehour "Hour", s_key "SensorKey",
6 sum(duration) "Duration", min(s_time) "StartTime", max(e_time) "EndTime"
7 from (select block_start, thehour, s_key, duration, s_time, e_time
8 from data
9 model partition by (id as key)
10 dimension by (0 as f)
11 measures (s_key, s_time, e_time,
12 cast(2 as number(2,0)) duration, hours,
13 cast(null as number(2)) thehour,
14 cast(null as date) block_start,
15 cast(null as date) block_end)
16 rules (block_start[for f from 0 to hours[0]-1 increment 1] = trunc(s_time[0] + (cv(f)/24), 'hh24'),
17 block_end[any] = trunc(s_time[0] + ((cv(f)+1)/24), 'hh24'),
18 s_key[any] = s_key[0],
19 s_time[any] = s_time[0],
20 e_time[any] = e_time[0],
21 duration [any] = case
22 when cv(f) = 0
23 then (least(block_end[cv(f)],e_time[0]) - s_time[0]) * 24*60
24 when cv(f) = hours[0]-1
25 then (e_time[0] - block_start[cv(f)] ) * 24*60
26 else (block_end[cv(f)] - block_start[cv(f)] ) * 24*60
27 end,
28 thehour[any] = to_char(s_time[0] + (cv(f)/24), 'hh24')
29 ))
30 group by block_start, thehour, s_key
31 order by 5, 2;
TimeKey Hour SensorKey Duration StartTime EndTime
-------- ---------- ---------- ---------- ----------------- -----------------
20121017 8 45 29 17-oct-2012 08:31 17-oct-2012 10:21
20121017 9 45 60 17-oct-2012 08:31 17-oct-2012 10:21
20121017 10 45 46 17-oct-2012 08:31 17-oct-2012 10:51
20121017 12 45 24 17-oct-2012 12:21 17-oct-2012 13:41
20121017 13 45 50 17-oct-2012 12:41 17-oct-2012 14:46
20121017 14 45 46 17-oct-2012 13:51 17-oct-2012 14:46
20121017 15 45 19 17-oct-2012 15:11 17-oct-2012 16:21
20121017 16 45 21 17-oct-2012 15:46 17-oct-2012 16:21
20121017 18 45 5 17-oct-2012 18:51 17-oct-2012 18:56
20121017 19 45 45 17-oct-2012 19:11 17-oct-2012 19:56
20121017 20 45 34 17-oct-2012 20:26 17-oct-2012 21:11
20121017 21 45 11 17-oct-2012 20:26 17-oct-2012 21:11
20121017 22 45 35 17-oct-2012 22:16 17-oct-2012 22:56
20121018 0 45 60 17-oct-2012 23:36 18-oct-2012 01:46
20121018 1 45 46 17-oct-2012 23:36 18-oct-2012 01:46
20121017 23 45 24 17-oct-2012 23:36 18-oct-2012 01:46
20121018 2 45 40 18-oct-2012 02:16 18-oct-2012 02:56
20121018 3 45 29 18-oct-2012 03:31 18-oct-2012 15:06
20121018 4 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 5 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 6 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 7 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 8 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 9 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 10 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 11 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 12 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 13 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 14 45 60 18-oct-2012 03:31 18-oct-2012 15:06
20121018 15 45 35 18-oct-2012 03:31 18-oct-2012 16:41
20121018 16 45 41 18-oct-2012 15:31 18-oct-2012 16:41
20121018 17 45 19 18-oct-2012 17:41 18-oct-2012 18:06
20121018 18 45 6 18-oct-2012 17:41 18-oct-2012 18:06
20121018 19 45 15 18-oct-2012 19:16 18-oct-2012 19:41
20121018 20 45 9 18-oct-2012 20:51 18-oct-2012 23:16
20121018 21 45 60 18-oct-2012 20:51 18-oct-2012 23:16
20121018 22 45 60 18-oct-2012 20:51 18-oct-2012 23:16
20121018 23 45 16 18-oct-2012 20:51 18-oct-2012 23:16
20121019 0 45 50 19-oct-2012 00:01 19-oct-2012 00:51
39 rows selected.
一些说明: 首先,我计算了每行所需的小时数。
SQL> select rownum id, "SensorKey" s_key, cast("StartTime" as date) s_time, cast("EndTime" as date) e_time,
2 ((trunc(cast("EndTime" as date) , 'hh24') -trunc(cast("StartTime" as date), 'hh24')) *24)+1 hours
3 from table1;
ID S_KEY S_TIME E_TIME HOURS
---------- ---------- ----------------- ----------------- ----------
1 45 17-oct-2012 08:31 17-oct-2012 10:21 3
这个“HOURS”列将驱动model子句,告诉它每个源行要生成多少行。 rownum ID就是一个唯一的密钥(因为其他数据似乎并不能保证唯一性)。
我在ID
上进行了分区model partition by (id as key)
这意味着我们将每一行作为单独处理。
在测量中我们列出了我们将要使用的字段(计算或只是输出)。
measures (s_key, s_time, e_time,
cast(null as number(2,0)) duration, hours,
cast(null as number(2)) thehour,
cast(null as date) block_start,
cast(null as date) block_end)
cast()
列只是不在原始集中的列,而是我们将要计算的列。
duration
将保留会议记录,thehour
将显示小时编号,blocks
将保留当前小时所适合的小时位。
规则是我们所有逻辑完成的地方。所以:
rules (block_start[for f from 0 to hours[0]-1 increment 1] = trunc(s_time[0] + (cv(f)/24), 'hh24'),
"for f from 0 to hours[0]-1 increment 1"
表示我们根据HOURS
列生成行(第一行为3行)。
块开始将在第一行设置为17-oct-2012 08:00
并阻止结束09:00
(在第2行,我们将它们提升一小时,依此类推。
s_key[any] = s_key[0],
s_time[any] = s_time[0],
e_time[any] = e_time[0],
将上述三项简单地复制到输出集中。 ANY关键字意味着匹配所有行(我们可以在这里放置“for f ..”逻辑,但ANY更整洁。
持续时间使用案例陈述
计算 case
when cv(f) = 0
then (least(block_end[cv(f)],e_time[0]) - s_time[0]) * 24*60
when cv(f) = hours[0]-1
then (e_time[0] - block_start[cv(f)] ) * 24*60
else (block_end[cv(f)] - block_start[cv(f)] ) * 24*60
end
即。 cv(f) = 0
表示第一个输出行(cv
bieng函数,用于访问本例中F
变量的“当前值”。
所以第一行,我们采用块结束(17-oct-2012 09:00
) - 开始时间(17-oct-2012 08:31
)并在几分钟(29分钟)内得到。
对于结束行,我们再次采用结束时间(17-oct-2012 10:21
) - 块开始(17-oct-2012 10:00
)= 21分钟
对于中间的所有行,我们只是从块开始(即60分钟)中扣除块结束
这会给我们输出:
TimeKey Hour SensorKey Duration StartTime EndTime
-------- ---------- ---------- ---------- ----------------- -----------------
20121017 8 45 29 17-oct-2012 08:31 17-oct-2012 10:21
20121017 9 45 60 17-oct-2012 08:31 17-oct-2012 10:21
20121017 10 45 21 17-oct-2012 08:31 17-oct-2012 10:21
20121017 10 45 25 17-oct-2012 10:26 17-oct-2012 10:51
...etc..
但你说组合了“10”行,所以现在它是一个简单的组来完成这个:
select to_char(block_start, 'yyyymmdd') "TimeKey",
thehour "Hour", s_key "SensorKey",
sum(duration) "Duration", min(s_time) "StartTime", max(e_time) "EndTime"
from (..our model query...)
group by block_start, thehour, s_key;