Need help to write sql queries that involve multiple filters on same field of a table.
I have 2 tables as shown below.
Job
table:
ID JobId Name StartTime FinishTime
01 001 A 2105:12:10 14:00:00 2105:12:10 14:00:10
02 002 A 2105:12:10 14:00:00 2105:12:10 14:00:00
03 003 A 2105:12:10 14:00:00 2105:12:10 14:00:00
04 004 A 2105:12:10 14:00:00 2105:12:10 14:00:00
and
Status
table:
ID Status Timestamp JobId
01 Started 2105:12:10 14:00:00 001
02 Step_1_Started 2105:12:10 14:00:00 001
03 Step_1_Finished 2105:12:10 14:00:05 001
04 Step_2_Started 2105:12:10 14:00:05 001
05 Step_2_Finished 2105:12:10 14:00:10 001
06 Finished 2105:12:10 14:00:10 001
........................................................
07 Started 2105:12:10 14:00:00 002
08 Step_1_Started 2105:12:10 14:00:00 002
09 Step_1_Failed 2105:12:10 14:00:02 002
........................................................
10 Started 2105:12:10 14:00:00 003
11 Step_1_Started 2105:12:10 14:00:00 003
12 Step_1_Failed 2105:12:10 14:00:02 003
13 Step_1_Canceled 2105:12:10 14:00:04 003
........................................................
14 Started 2105:12:10 14:00:00 004
15 Step_1_Started 2105:12:10 14:00:00 004
From these 2 tables I have to query for jobs having states FINISHED, CANCELED, FAILED and ACTIVE where
I have the following SQL query for Finished
that works fine
SELECT
j.jobid
FROM
Job j
JOIN
status js ON j.jobid = js.jobid
WHERE
j.startTime >= '2015:12:10'
AND j.startTtime < '2015:12:20'
AND js.status = 'Finished';
Need help for other queries.
Expected output:
FINISHED: 001
CANCELED: 003
FAILED: 002
Active: 004
Thanks in advance.
The version for Oracle is:
with jobList (jobid, steps) as (
select jobid, listagg(Status, ' ') WITHIN GROUP (ORDER BY id) from job_status
group by jobid )
select 'FINISHED:' as Status , listagg(jobid, ' ') WITHIN GROUP (ORDER BY jobid) from jobList
where instr(steps, 'Finished') > 0
union all
select 'CANCELED:' as Status , listagg(jobid, ' ') WITHIN GROUP (ORDER BY jobid) from jobList
where instr(steps, 'Finished') = 0 and instr(steps, 'Canceled') > 0
union all
select 'FAILED:' as Status , listagg(jobid, ' ') WITHIN GROUP (ORDER BY jobid) from jobList
where instr(steps, 'Failed') > 0 and instr(steps, 'Canceled') = 0 and instr(steps, 'Finished') = 0
union all
select 'Active:' as Status , listagg(jobid, ' ') WITHIN GROUP (ORDER BY jobid) from jobList
where instr(steps, 'Started') > 0 and instr(steps, 'Failed') = 0 and instr(steps, 'Canceled') = 0 and instr(steps, 'Finished') = 0
Basically I put all statuses for each jobid
to one string that is called steps
.
After that I search in string if specific status exists or not. As there can be more than one jobid
for such criteria I use listagg
again to change result to string. In case you will have 2 finished jobs (with id 1 and 5) , you will see FINISHED: 1 5
The version for MySql with sample SQL Fiddle. It's a little bit longer as we don't have WITH
on MySql.
select 'FINISHED:' as Status ,
group_concat( a.jobid separator ' ') as jobList
from
( select jobid,
group_concat(Status separator ' ') steps
from job_status
group by jobid ) a
where instr(steps, 'Finished') > 0
union all
select 'CANCELED:' as Status ,
group_concat( a.jobid separator ' ') as jobList
from
( select jobid,
group_concat(Status separator ' ') steps
from job_status
group by jobid ) a
where instr(steps, 'Finished') = 0 and
instr(steps, 'Canceled') > 0
union all
select 'FAILED:' as Status ,
group_concat( a.jobid separator ' ') as jobList
from
( select jobid,
group_concat(Status separator ' ') steps
from job_status
group by jobid ) a
where instr(steps, 'Failed') > 0 and
instr(steps, 'Canceled') = 0 and
instr(steps, 'Finished') = 0
union all
select 'Active:' as Status ,
group_concat( a.jobid separator ' ') as jobList
from
( select jobid,
group_concat(Status separator ' ') steps
from job_status
group by jobid ) a
where instr(steps, 'Started') > 0 and
instr(steps, 'Failed') = 0 and
instr(steps, 'Canceled') = 0 and
instr(steps, 'Finished') = 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With