Reputation: 181
Hi I want to know the job execution time based on the table below. For example 1/24/17 , The time difference between Running and Completed is 17min.
**JobName** **CurrentJobStatus** **TimeOfChange**
Customer Completed 1/24/17 0:17
Customer Running 1/24/17 0:00
Customer Waiting 1/23/17 20:30
Customer Completed 1/21/17 0:47
Customer Idle 1/21/17 16:00
Customer Running 1/21/17 0:30
Customer Completed 1/20/17 0:31
Customer Idle 1/20/17 16:00
Customer Running 1/20/17 0:15
Customer Waiting 1/20/17 20:30
Customer Completed 1/19/17 0:37
Customer Idle 1/19/17 16:00
Customer Running 1/19/17 0:20
Customer Waiting 1/19/17 20:30
Upvotes: 1
Views: 50
Reputation: 1269823
This can be tricky. If we assume that "Running" and "Completed" are completely interwoven (no two "Running" followed by a "Completed"), then you can identify matches by counting the number of "Running" records on or before each record. The rest is just aggregation:
select min(case when CurrentJobStatus = 'Running' then TimeOfChange end) as running_time,
max(case when CurrentJobStatus = 'Completed' then TimeOfChange end) as completed_time,
datediff(minute,
min(case when CurrentJobStatus = 'Running' then TimeOfChange end),
max(case when CurrentJobStatus = 'Completed' then TimeOfChange end)
) as diff_in_minutes
from (select t.*,
sum(case when CurrentJobStatus = 'Running' then 1 else 0 end) over (order by TimeOfChange) as running_running
from t
) t
group by running_running;
If the assumption is not true and you can have multiple "running" in a row or "completed" in a row, then you should ask another question with appropriate sample data and the description of the rules.
Upvotes: 1
Reputation: 10807
I've selected rows with CurrentJobStatus in ('Completed', 'Running'), and then I've set a rank by CurrentJobStatus ordered by TimeOfChange. This adds a sequenced number for every pair of ('Completed', 'Running')
Finally grouping by this rank, get datediff between max and min date.
with tm as
(
select JobName, CurrentJobStatus, TimeOfChange,
rank() over (partition by CurrentJobStatus order by TimeOfChange desc) rn
from jobs
where CurrentJobStatus in ('Completed', 'Running')
)
select
rn, DateDiff(minute, min(TimeOfChange), max(TimeOfChange)) as min
from tm
group by rn;
Check it here: http://rextester.com/NZFWXO47289
Upvotes: 1
Reputation: 32392
Assuming there's only 1 Running
and Completed
job status per day and you want the time difference between the two, you can use conditional aggregation by putting a case
statement inside max
or min
:
select * , datediff(minute, completed, running)
from (
select
convert(date, TimeOfChange) change_date,
max(case when CurrentJobStatus = 'Completed' then TimeOfChange end) completed,
min(case when CurrentJobStatus = 'Running' then TimeOfChange end) running
from mytable
group by convert(date, TimeOfChange)
) t order by change_date
Upvotes: 1