获取没有指定子项的父(作业)的SQL查询(状态)

时间:2015-12-17 06:03:46

标签: sql

需要帮助来编写涉及表的同一字段上的多个过滤器的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

提前致谢。

1 个答案:

答案 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