Reputation: 1153
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
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
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