Dean
Dean

Reputation: 1153

Calculate number of instance running at a particular time frame

Hi I'd like to calculate number of batch running instance for a particular time slice. For example, I've a table:

BatchID startTime   endTime
12957   10:15   10:25
13032   10:16   10:20
13080   10:16   10:22
13090   10:16   10:20
13214   10:19   10:30
13232   10:19   10:22
13276   10:19   10:29
13279   10:19   10:30
13315   10:20   10:23
13341   10:20   10:24
13430   10:22   10:33
13566   10:27   10:30
13580   10:27   10:31
13585   10:28   10:31
13596   10:28   10:32
13626   10:30   10:42
13637   10:32   10:35
13699   10:40   10:44
13702   10:41   10:45

The number of instance running at 10:41 would be 3, and the running batches are: BatchID 13626, 13699 and 13702.

To visualise this problem, I have a chat with a time slice from 10:15 to 10:41 with a step of 1 minutes as the x-axis,and the number of instance running at that time slice as the y-axis. I'm thinking to implement in ORACLE(SQL/PLSQL) or EXCEL(function/VBA/Pivot Table/etc.), what's your advise?

Upvotes: 1

Views: 155

Answers (2)

Markus Jarderot
Markus Jarderot

Reputation: 89221

To list all at a particular time:

SELECT BatchID, startTime, endTime
FROM Batch
WHERE :instanceTime BETWEEN startTime AND endTime

Or just count them:

SELECT COUNT(*) AS numConcurrent
FROM Batch
WHERE :instanceTime BETWEEN startTime AND endTime

But if you need to query it for every time in some interval, it is quicker to query all batches inside your interval, and count them with some programming logic.

SELECT startTime, endTime
FROM Batch
WHERE endTime > :intervalStart
AND startTime < :intervalEnd
ORDER BY startTime

:instanceTime is a query parameter. The parameters are replaced with values you provide alongside the query, and you don't need to worry about formatting and escaping. (Some data providers use ? for parameters.)

If you can't use parameters, you could replace them with an actual value. Don't forget to use to_date() in that case.


Here is some example usage of date parameters in VBA:
Bytes.com: How to pass date parameter into Oracle SQL string in VBA

Upvotes: 2

Rob van Wijk
Rob van Wijk

Reputation: 17705

Creating your sample table:

SQL> create table mytable (batchid,starttime,endtime)
  2  as
  3  select 12957, '10:15', '10:25' from dual union all
  4  select 13032, '10:16', '10:20' from dual union all
  5  select 13080, '10:16', '10:22' from dual union all
  6  select 13090, '10:16', '10:20' from dual union all
  7  select 13214, '10:19', '10:30' from dual union all
  8  select 13232, '10:19', '10:22' from dual union all
  9  select 13276, '10:19', '10:29' from dual union all
 10  select 13279, '10:19', '10:30' from dual union all
 11  select 13315, '10:20', '10:23' from dual union all
 12  select 13341, '10:20', '10:24' from dual union all
 13  select 13430, '10:22', '10:33' from dual union all
 14  select 13566, '10:27', '10:30' from dual union all
 15  select 13580, '10:27', '10:31' from dual union all
 16  select 13585, '10:28', '10:31' from dual union all
 17  select 13596, '10:28', '10:32' from dual union all
 18  select 13626, '10:30', '10:42' from dual union all
 19  select 13637, '10:32', '10:35' from dual union all
 20  select 13699, '10:40', '10:44' from dual union all
 21  select 13702, '10:41', '10:45' from dual
 22  /

Table created.

Introducing the start and the end of the interval you want to report on, as bind variables. You can recognize the use of bind variables in SQL and PL/SQL by their leading colons.

SQL> var START_X_AXIS varchar2(5)
SQL> var END_X_AXIS varchar2(5)
SQL> begin
  2    :START_X_AXIS := '10:15';
  3    :END_X_AXIS := '10:41';
  4  end;
  5  /

PL/SQL procedure successfully completed.

And a query that's executed in three phases for sake of clarity. First transforming your varchar2 times to real dates (advice is to store them like that as well, by the way). The second query shows all minutes on the X-axis for your report. The third one does the counting.

SQL> with mytable_with_real_dates as
  2  ( select batchid
  3         , to_date(starttime,'hh24:mi') starttime
  4         , to_date(endtime,'hh24:mi') endtime
  5      from mytable
  6  )
  7  , all_minutes as
  8  ( select to_date(:START_X_AXIS,'hh24:mi') + numtodsinterval(level-1,'minute') minute
  9      from dual
 10   connect by level <=  24 * 60 * (to_date(:END_X_AXIS,'hh24:mi') - to_date(:START_X_AXIS,'hh24:mi')) + 1
 11  )
 12  select to_char(m.minute,'hh24:mi')
 13       , count(t.batchid)
 14    from all_minutes m
 15         left outer join mytable_with_real_dates t on (m.minute between t.starttime and t.endtime)
 16   group by m.minute
 17   order by m.minute
 18  /

TO_CH COUNT(T.BATCHID)
----- ----------------
10:15                1
10:16                4
10:17                4
10:18                4
10:19                8
10:20               10
10:21                8
10:22                9
10:23                7
10:24                6
10:25                5
10:26                4
10:27                6
10:28                8
10:29                8
10:30                8
10:31                5
10:32                4
10:33                3
10:34                2
10:35                2
10:36                1
10:37                1
10:38                1
10:39                1
10:40                2
10:41                3

27 rows selected.

EDIT: I just saw your comment that your columns are stored as dates. That's good news, so you can skip the first part and start with line number 7, replacing the comma with the word "WITH".

Regards,
Rob.

Upvotes: 1

Related Questions