如何计算一个时间段之间的条目数

时间:2019-12-03 02:32:59

标签: sql oracle

我下面有一个示例表,其中显示了票证编号,票证打开时间和票证关闭时间。

TKTNUM  OPEN_DATE           CLOSE_DATE
1234    12-Mar-19 08:36     14-Mar-19 08:36
1235    13-Mar-19 08:36     15-Mar-19 08:36
1236    14-Mar-19 08:36     16-Mar-19 08:36
1237    15-Mar-19 08:36 
1238    16-Mar-19 08:36 
1239    17-Mar-19 08:36 
1240    18-Mar-19 08:36     20-Mar-19 08:36
1241    19-Mar-19 08:36     20-Mar-19 08:36
1242    20-Mar-19 08:36     21-Mar-19 08:36

我需要计算给定日期的开/关票数量...

DATE                OPEN        CLOSED
12-Mar-19 08:36     1           0
13-Mar-19 08:36     2           0
14-Mar-19 08:36     2           1
15-Mar-19 08:36     2           2
16-Mar-19 08:36     2           3
17-Mar-19 08:36     3           3
18-Mar-19 08:36     4           3
19-Mar-19 08:36     5           3
20-Mar-19 08:36     4           5

任何帮助将不胜感激。谢谢


在示例job_history表上使用了以下查询(c / o Tejash)

EMPLOYEE_ID START_DATE           END_DATE             JOB_ID     DEPARTMENT_ID
----------- -------------------- -------------------- ---------- -------------
        200 17/SEP/1995 00:00:00 17/JUN/2001 00:00:00 AD_ASST               90
        101 21/SEP/1997 00:00:00 27/OCT/2001 00:00:00 AC_ACCOUNT           110
        102 13/JAN/2001 00:00:00 24/JUL/2006 00:00:00 IT_PROG               60
        101 28/OCT/2001 00:00:00 15/MAR/2005 00:00:00 AC_MGR               110
        200 01/JUL/2002 00:00:00 31/DEC/2006 00:00:00 AC_ACCOUNT            90
        201 17/FEB/2004 00:00:00 19/DEC/2007 00:00:00 MK_REP                20
        114 24/MAR/2006 00:00:00 31/DEC/2007 00:00:00 ST_CLERK              50
        176 24/MAR/2006 00:00:00 31/DEC/2006 00:00:00 SA_REP                80
        176 01/JAN/2007 00:00:00 31/DEC/2007 00:00:00 SA_MAN                80
        122 01/JAN/2007 00:00:00 31/DEC/2007 00:00:00 ST_CLERK              50

With dates(dt)
As (Select mindt + level - 1 from
        (Select min(start_date) mindt, max(end_date) maxdt from job_history)
      Connect by level <= maxdt - mindt + 1)
Select dt, 
       sum(case when dt between start_date and coalesce(end_date,dt) then 1 end) as startdate, 
       Sum(case when dt >= end_date then 1 end) as enddate
From dates cross join job_history
Group by dt 
Order by dt desc

2001年6月17日,查询给出了

DT                    STARTDATE    ENDDATE
-------------------- ---------- ----------
31/DEC/2007 00:00:00          3         10
<SNIPPED>
17/JUN/2001 00:00:00          3          1

代替

DT                    STARTDATE    ENDDATE
-------------------- ---------- ----------
31/DEC/2007 00:00:00          3         10
<SNIPPED>
17/JUN/2001 00:00:00          2          1

试图编辑查询,现在它给了我

DT                    STARTDATE    ENDDATE
-------------------- ---------- ----------
31/DEC/2007 00:00:00             <<<    10   
<snipped>
18/JUN/2001 00:00:00          2          1
17/JUN/2001 00:00:00          2  <<<     1   
16/JUN/2001 00:00:00          3          1

2 个答案:

答案 0 :(得分:1)

您可以取消透视和聚合:

select dte, sum(is_open) as num_opens, sum(is_close) as num_closes
from ((select open_date as dte, 1 as is_open, 0 as is_close
       from t
      ) union all
      (select close_date, 0 as is_open, 1 as is_close
       from t
      ) 
     ) t
group by dte
order by dte;

注意:截断日期可能是一个好主意,因此它没有时间部分:

select trunc(dte), sum(is_open) as num_opens, sum(is_close) as num_closes
from ((select open_date as dte, 1 as is_open, 0 as is_close
       from t
      ) union all
      (select close_date, 0 as is_open, 1 as is_close
       from t
      ) 
     ) t
where dte is not null
group by trunc(dte)
order by trunc(dte);

在Oracle 12C中,您可以为此使用横向join

select trunc(dte), sum(is_open), sum(is_close)
from t cross join lateral
     (select t.open_date as dte, 1 as is_open, 0 as is_close from dual union all
      select t.close_date, 0 as is_open, 1 as is_close from dual
     ) t
group by trunc(dte)
order by trunc(dte);

答案 1 :(得分:1)

您可以将日期用作总天数的cte,然后使用以下相同的表格再次将其加入:

With dates(dt)
As
(
Select mindt + level - 1 from
  (Select min(open_date) mindt, max(open_dt) maxdt from your_table)
Connect by level <= maxdt - mindt + 1
)
Select dt, 
       sum(case when dt between open_date and coalesce(close_date,dt) then 1 end) as open, 
       Sum(case when dt >= close_date then 1 end) as closed
From dates cross join your_table
Group by dt;

干杯!

相关问题