需要帮助来编写涉及表的同一字段上的多个过滤器的SQL查询。
我有2个表,如下所示。
Job
表:
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
和
Status
表:
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
从这两个表中我必须查询状态为FINISHED,CANCELED,FAILED和ACTIVE的作业
我有Finished
的以下SQL查询可以正常工作
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';
需要其他查询的帮助。
预期产出:
FINISHED: 001
CANCELED: 003
FAILED: 002
Active: 004
提前致谢。
答案 0 :(得分:1)
Oracle的版本是:
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
基本上,我将每个jobid
的所有状态都放在一个名为steps
的字符串中。
之后我搜索字符串是否存在特定状态。由于此类条件可以有多个jobid
,我再次使用listagg
将结果更改为字符串。如果您有2个已完成的工作(ID为1和5),您将看到FINISHED: 1 5
样本为SQL Fiddle的MySql版本。由于我们在MySql上没有WITH
,所以要长一点。
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