I have these 2 tables and their inserts:
x
create table #JobFailureConfig (
JobId int not null,
JobName varchar(128) not null);
go
insert into #JobFailureConfig values (2, 'CopyOverFileJob');
insert into #JobFailureConfig values (3, 'ExcludeFromWarehouseJob');
go
create table #Job(
id int,
JobId int,
CreateDtTm datetimeoffset,
StatusDtTm datetimeoffset,
StatusName varchar(128));
go
insert into #Job values (47022087, 3, '2020-05-07 18:44:35.7327 -07:00', '2020-05-07 18:44:36.6599 -07:00','Failed');
insert into #Job values (47022092, 3, '2020-05-07 18:44:47.1431 -07:00', '2020-05-07 18:44:47.2599 -07:00','Failed');
insert into #Job values (47022097, 3, '2020-05-07 18:45:36.6888 -07:00', '2020-05-07 18:45:36.8439 -07:00','Failed');
insert into #Job values (47022088, 3, '2020-05-07 18:46:35.7327 -07:00', '2020-05-07 18:47:36.6599 -07:00','Finished');
insert into #Job values (47022087, 3, '2020-05-07 18:44:35.7327 -07:00', '2020-05-13 18:44:36.6599 -07:00','Failed');
insert into #Job values (47022092, 3, '2020-05-07 18:44:47.1431 -07:00', '2020-05-13 18:44:47.2599 -07:00','Failed');
insert into #Job values (98234237, 2, '2020-05-01 18:44:35.7327 -07:00', '2020-05-01 18:44:36.6599 -07:00','Finished');
insert into #Job values (98234238, 2, '2020-05-03 18:44:35.7327 -07:00', '2020-05-03 18:44:36.6599 -07:00','Failed');
insert into #Job values (98234238, 2, '2020-05-03 18:44:35.7327 -07:00', '2020-04-03 18:44:36.6599 -07:00','Failed');
go
I have this query to partition them by JobId
and order them by JobId
and StatusDtTm
:
select
j.Id,
j.JobId,
jfc.JobName,
j.StatusName,
CreateDtTm = format(cast(CreateDtTm as datetime), 'yyyy-MM-dd HH:mm:ss'),
StatusDtTm = format(cast(StatusDtTm as datetime), 'yyyy-MM-dd HH:mm:ss'),
row_number() over (Partition by j.JobId order by j.JobId, j.StatusDtTm desc) as JobFailureId
from #Job j
join #JobFailureConfig jfc
on j.JobId = jfc.JobId;
go
I want to fetch only the rows where the Job last finished per job. Basically get all the records per job before it last finished (highlighted in green). I can’t seem to figure out what to add in the where clause here to get the highlighted result. Can someone help please?
Advertisement
Answer
One approach is to add the following column to your query:
count(case when statusname = 'Finished' then 1 end)
over(partition by j.jobid
order by j.StatusDtTm
rows between unbounded preceding and current row) sel
This new field sel
will have a nonzero value for the highlighted rows, where a current or a previous StatusName
for that job ID has the value ‘Finished’; otherwise, the value will be zero.
The full query to output only the highlighted records is then:
with cte as
(
select
j.Id,
j.JobId,
jfc.JobName,
j.StatusName,
format(cast(CreateDtTm as datetime), 'yyyy-MM-dd HH:mm:ss') as CreateDtTm,
format(cast(StatusDtTm as datetime), 'yyyy-MM-dd HH:mm:ss') as StatusDtTm,
row_number() over (Partition by j.JobId order by j.JobId, j.StatusDtTm desc) as JobFailureId,
count(case when statusname = 'Finished' then 1 end)
over(partition by j.jobid
order by j.StatusDtTm
rows between unbounded preceding and current row) sel
from #Job j
join #JobFailureConfig jfc
on j.JobId = jfc.JobId
)
select Id, JobId, JobName, StatusName, CreateDtTm, StatusDtTm, JobFailureId
from cte
where sel=1
order by jobid, jobfailureid