【问题标题】:SQL query to get parent (job) that does not have specified children (status)获取没有指定子项(状态)的父项(作业)的 SQL 查询
【发布时间】:2015-12-17 06:03:46
【问题描述】:

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

我必须从这 2 个表中查询具有 FINISHED、CANCELED、FAILED 和 ACTIVE 状态的作业

  • 已完成:状态为“已完成”的作业。
  • CANCELED:状态为“%Canceled”但不是(“Finished”)的作业。
  • FAILED:状态为“%Failed”但不是(“%Canceled”或“Finished”)状态的作业。
  • 活动:状态为“%Started”但不是(“%Failed”或“%Canceled”或“Finished”)的作业。

我有以下针对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

提前致谢。

【问题讨论】:

  • Oracle 还是 mysql?这是两种不同的产品。到目前为止你做了什么?
  • 使用嵌套选择对你有帮助吗?
  • 我不想要特定于数据库的查询,所以我添加了 Oracle 和 mysql。
  • @Ajay:我正在尝试嵌套选择,但不适用于 CANCELED 和 ACTIVE 作业。对于 FAILED 我写了 select distinct j.jobid from status js1, job j where not exists ( select 1 from status js2 where js2.jobid=js1.jobid and js2.status = 'Finished' ) 和 js1.status like '%Failed'和 j.jobid=js1.jobid 和 j.startTime >= '2015:12:10' AND j.startTime
  • 您为什么不想要一个特定于数据库的查询?每个数据库的语法都不同。如果您想要一个真正的最低公分母查询,它的效率通常会低得多。如果您不想要 Oracle 或 MySQL 解决方案,请不要为任一数据库标记问题,并在问题中明确说明您的限制是什么。

标签: sql


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多