2015-12-17 79 views
5

テーブルの同じフィールドに複数のフィルタを含む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表:私はFINISHED状態を持つジョブを照会する必要があり、これらの2つのテーブルから

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 

キャンセル、失敗し、ACTIVEどこ

  • 終了:ステータスが「完了」のジョブ。
  • CANCELED:ステータス '%キャンセル済み'( '完了')のジョブ。
  • FAILED:ステータスが '失敗しました'( '%キャンセル済み'または '終了済み')のジョブ。
  • アクティブ: '%開始済み'ステータス( '%失敗'または '%キャンセル'または '終了済み')を持つジョブ。

は、私は他のクエリのために助けが必要

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に対して次のSQLクエリを持っています。

予想される出力:事前に

FINISHED: 001 
CANCELED: 003 
FAILED: 002 
Active: 004 

感謝。

+1

Oracleまたはmysql?これらは2つの異なる製品です。これまで何をしていますか? – Shadow

+0

ネストされた選択を使用すると、何か試してみることができますか? –

+0

データベース固有のクエリが不要なので、Oracleとmysqlを追加しました。 – jitk

答えて

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 

基本的に私はstepsと呼ばれている各jobid 1の文字列のすべてのステータスを置きます。 その後、特定のステータスが存在するかどうかを文字列で検索します。そのような基準には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 
関連する問題