我需要在一小时的时间内将每行数据分开,给出一小时的差异。 我从以下数据开始:
我想输出这个结果:
Tally是两个日期之间事件发生的次数,New_date将是每个段的开始,new_tally是原始计数的一个除以每个段的时间比例。
我已经尝试在另一个question中执行sqlfiddle,但是我收到以下错误:
ORA-01436:用户数据中的CONNECT BY循环
来自小提琴的确切代码:
create table log_table
( dt1 date, dt2 date
);
insert into log_table values(sysdate,sysdate-5/24);
select greatest(dt2, trunc(dt2+(level-1)/24, 'hh24')), least(dt1, trunc(dt2+(level)/24, 'hh24'))
from log_table connect by level <= floor((dt1-dt2)*24)+1;
这可能与我在Oracle 8i数据库中尝试此事实有关。我也一直试图理解分层查询是如何工作的,但我发现它们真的很复杂。
有人能给我一个例子并解释发生了什么吗?提前谢谢。
内加。
答案 0 :(得分:1)
我不确定8i对此有多开心,但您可以使用以下分层查询将记录分成小时(或部分小时)块:
select firstoccurrence, lastoccurrence, tally,
greatest(firstoccurrence,
trunc(firstoccurrence, 'HH24') + (level - 1) / 24) as new_start,
least(lastoccurrence,
trunc(firstoccurrence, 'HH24') + level / 24) as new_end
from t42
connect by firstoccurrence = prior firstoccurrence
and prior sys_guid() is not null
and trunc(firstoccurrence, 'HH24') + (level - 1) / 24
<= trunc(lastoccurrence, 'HH24');
...其中t42是填充在第一张图片中的表格。这给了:
FIRSTOCCURRENCE LASTOCCURRENCE TALLY NEW_START NEW_END
------------------- ------------------- ----- ------------------- -------------------
2014-12-04 11:33:16 2014-12-04 11:33:36 1 2014-12-04 11:33:16 2014-12-04 11:33:36
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 11:41:46 2014-12-30 12:00:00
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 12:00:00 2014-12-30 13:00:00
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 13:00:00 2014-12-30 14:00:00
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 14:00:00 2014-12-30 15:00:00
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 15:00:00 2014-12-30 16:00:00
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 16:00:00 2014-12-30 16:23:08
然后您可以将其用作CTE,或者我认为8i不知道CTE是内联视图,并计算每个时间与原始范围的比例之间的差异,并将该分数除以:< / p>
select firstoccurrence, lastoccurrence, tally, new_start, new_end,
to_number(to_char(new_start, 'HH24')) as new_hour,
tally / ((lastoccurrence - firstoccurrence) / (new_end - new_start)) as new_tally
from (
select firstoccurrence, lastoccurrence, tally,
greatest(firstoccurrence,
trunc(firstoccurrence, 'HH24') + (level - 1) / 24) as new_start,
least(lastoccurrence,
trunc(firstoccurrence, 'HH24') + level / 24) as new_end
from t42
connect by firstoccurrence = prior firstoccurrence
and prior sys_guid() is not null
and trunc(firstoccurrence, 'HH24') + (level - 1) / 24
<= trunc(lastoccurrence, 'HH24')
);
FIRSTOCCURRENCE LASTOCCURRENCE TALLY NEW_START NEW_END NEW_HOUR NEW_TALLY
------------------- ------------------- ----- ------------------- ------------------- -------- -----------
2014-12-04 11:33:16 2014-12-04 11:33:36 1 2014-12-04 11:33:16 2014-12-04 11:33:36 11 1.000000
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 11:41:46 2014-12-30 12:00:00 11 .453619
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 12:00:00 2014-12-30 13:00:00 12 1.492714
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 13:00:00 2014-12-30 14:00:00 13 1.492714
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 14:00:00 2014-12-30 15:00:00 14 1.492714
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 15:00:00 2014-12-30 16:00:00 15 1.492714
2014-12-30 11:41:46 2014-12-30 16:23:08 7 2014-12-30 16:00:00 2014-12-30 16:23:08 16 .575524
SQL Fiddle demo;但那是11gR2所以并不意味着它可以在8i中运行。不幸的是,我没有这么古老的版本进行测试。
如果你的表有一个ID列,那么对connect by prior
子句使用它 - 我必须使用firstoccurrence
并希望它是唯一的。您可能还需要使用dbms_random.value
代替sys_guid()
- 但非确定性函数会执行此操作。