另一种方法更蛮力,但它允许将间隔配置与报告区分开来。
它分三步进行:
1) 定义一天中每分钟的费率类型(如果需要,更改粒度)
create table day_config as
with helper as (
select
rownum -1 minute_id
from dual connect by level <= 24*60),
helper2 as (
select
minute_id,
trunc(minute_id/60) hour_no,
mod(minute_id,60) minute_no
from helper)
select
minute_id,hour_no, minute_no,
case when hour_no >= 22 or hour_no <= 5 then 0 else 1 end rate_id
from helper2;
select * from day_config order by minute_id;
MINUTE_ID HOUR_NO MINUTE_NO RATE_ID
---------- ---------- ---------- ----------
0 0 0 0
1 0 1 0
2 0 2 0
3 0 3 0
4 0 4 0
5 0 5 0
6 0 6 0
7 0 7 0
8 0 8 0
9 0 9 0
这里 rate_id 表示晚上,rate_id 1 表示一天。
优点是,您可以根据需要引入尽可能多的费率类型。
2) 扩展所需间隔的配置,例如到一整年。
所以现在我们有了一年中每一分钟的配置,即要应用的速率。
create or replace view year_config as
select my_date + MINUTE_ID / (24*60) minute_ts , MINUTE_ID, HOUR_NO, MINUTE_NO, RATE_ID from day_config
cross join
(select DATE '2017-01-01' + rownum -1 as my_date from dual connect by level <= 365)
order by 1,2;
select * from (
select * from year_config
order by 1)
where rownum <= 5;
MINUTE_TS MINUTE_ID HOUR_NO MINUTE_NO RATE_ID
------------------- ---------- ---------- ---------- ----------
01-01-2017 00:00:00 0 0 0 0
01-01-2017 00:01:00 1 0 1 0
01-01-2017 00:02:00 2 0 2 0
01-01-2017 00:03:00 3 0 3 0
01-01-2017 00:04:00 4 0 4 0
3) 报告就像加入我们的配置表一样简单,限制间隔(半开)并在 RATE 中分组。
select b, f,RATE_ID, count(*) minute_cnt
from tst join year_config c on c.MINUTE_TS >= tst.b and c.MINUTE_TS < tst.f
group by b, f,RATE_ID
order by b, f,RATE_ID;
B F RATE_ID MINUTE_CNT
------------------- ------------------- ---------- ----------
16-11-2017 21:25:00 16-11-2017 22:55:00 0 55
16-11-2017 21:25:00 16-11-2017 22:55:00 1 35
17-11-2017 05:45:00 17-11-2017 07:05:00 0 15
17-11-2017 05:45:00 17-11-2017 07:05:00 1 65
17-11-2017 18:00:00 17-11-2017 19:00:00 1 60
18-11-2017 23:00:00 19-11-2017 01:10:00 0 130