使用两个日期时间列

时间:2016-04-30 17:34:38

标签: oracle11g

我的表格包含两个时间戳 t1(事件开放日期) t2(事件结束日期)以及主键 eventid

如果事件是开放的,那么 t2 null 每当关闭时,相同的行将更新事件关闭日期 t2 。 例如,我想根据(t1) 01-apr-2016 10-apr-2016检查每天开放的问题数量

我必须根据选定的日期范围计算每天打开的事件数。 让我们说,如果在第一个APR 第一个APR 打开了eventid 1,并且在 10th-APR 时关闭了我正在计算 11日每天开启的问题数量-APR 然后它应该给我从第1-APR到第10-APR的开放事件1的数量。

表格结构: -

================================================
    EVENTID            T1               T2
================================================
       1           01-apr-2016      10-apr-2016
       2           02-apr-2016      08-apr-2016
       3           05-apr-2016      09-apr-2016

预期输出: -

==============================================================================
       DATE            TOTAL_OPEN_EVENTS
==============================================================================
    01-apr-2016            1
    02-apr-2016            2(1 issue open on 1st(not closed on 2nd) and 1 on 2nd)
    03-apr-2016            2
    04-apr-2016            2
    05-apr-2016            3
    06-apr-2016            3
    07-apr-2016            3
    08-apr-2016            2(1 issue got closed on 8th(which was opened on 2nd))
    09-apr-2016            2
    10-apr-2016            0

如何在Oracle数据库中进行这种计算?

2 个答案:

答案 0 :(得分:2)

要生成结束报告,您需要在所需范围内为每个日期添加一行。您可以使用日历表(如果可用),或者我发现在DUAL上使用CONNECT BY LEVEL < some_number使用查询可以很好地生成行。 (在这种情况下&#34; some_number&#34;将是您要报告的天数。) 从那里,您只需将各个日期加入事件表中的日期范围:

-- create table "events" table
create table event_date_ranges
as
select 1 as event_id, TO_DATE('2016-APR-01', 'YYYY-MM-DD') as start_date, TO_DATE('2016-APR-10', 'YYYY-MON-DD') as end_date from dual
union all
select 2 as event_id, TO_DATE('2016-APR-02', 'YYYY-MM-DD') as start_date, TO_DATE('2016-APR-08', 'YYYY-MON-DD') as end_date from dual
union all
select 3 as event_id, TO_DATE('2016-APR-05', 'YYYY-MM-DD') as start_date, TO_DATE('2016-APR-09', 'YYYY-MON-DD') as end_date from dual
;


with 
date_range_qry as 
(-- one way to set the start and end dates for your report
 select TO_DATE('2016-APR-01', 'YYYY-MM-DD') as report_start_date
      , TO_DATE('2016-APR-10', 'YYYY-MM-DD') as report_end_date
   from dual
)
, dates_qry
as
(
-- generate a row for all dates between 2016-APR-01 and 2016-APR-10
select report_start_date + ROWNUM - 1 as report_date
from dual 
     cross join
     date_range_qry drq
connect by level <= (drq.report_end_date - drq.report_start_date + 1)
)
select dq.report_date, count(edr.event_id) as total_open_events
  from dates_qry dq
       left outer join
       event_date_ranges edr
          on dq.report_date >= edr.start_date 
          and dq.report_date < edr.end_date
 group by dq.report_date
 order by dq.report_date

输出:

REPORT_DATE     TOTAL_OPEN_EVENTS
2016-APR-01     1
2016-APR-02     2
2016-APR-03     2
2016-APR-04     2
2016-APR-05     3
2016-APR-06     3
2016-APR-07     3
2016-APR-08     2
2016-APR-09     1
2016-APR-10     0

答案 1 :(得分:0)

  

你可以试试这个:

create table events_log
as
select 1 as event_id, TO_DATE('01-04-2016', 'DD/MM/YYYY') as T1, TO_DATE('10-04-2016', 'DD/MM/YYYY') as T2 from dual
union all
select 2 as event_id, TO_DATE('02-04-2016', 'DD/MM/YYYY') as T1, TO_DATE('08-04-2016', 'DD/MM/YYYY') as T2 from dual
union all
select 3 as event_id, TO_DATE('05-04-2016', 'DD/MM/YYYY') as T1, TO_DATE('09-04-2016', 'DD/MM/YYYY') as T2 from dual
;
--------------

select v.REPORT_DATE, count(t.EVENT_ID) as open_event
  from events_log t,
       (select to_date('01/04/2016', 'DD/MM/YYYY') + ROWNUM - 1 as report_date
          from dual
        connect by level <= (to_date('11/04/2016', 'DD/MM/YYYY') -
                   to_date('01/04/2016', 'DD/MM/YYYY') + 1)) v
 where t.T1(+) <= v.report_date
   and t.T2(+) >= v.report_date
 group by v.report_date
 order by v.report_date;

输出将是:

report_date open_event
01/04/2016  1
02/04/2016  2
03/04/2016  2
04/04/2016  2
05/04/2016  3
06/04/2016  3
07/04/2016  3
08/04/2016  3
09/04/2016  2
10/04/2016  1
11/04/2016  0