2015-12-17 7 views
5

Hai bisogno di aiuto per scrivere query SQL che coinvolgono più filtri sullo stesso campo di una tabella.Query SQL per ottenere genitore (lavoro) che non ha figli specificati (stato)

Ho 2 tabelle come mostrato di seguito.

Job tavolo:

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 

e

Status tavolo:

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 

Da queste 2 tabelle devo interrogare per i lavori che hanno stati finiti, annullato, fallito e attivo dove

  • FINITO: un processo con stato 'Finito'.
  • ANNULLATO: un processo con stato '% annullato' ma non ('Fine').
  • FAILED: un processo con stato '% non riuscito' ma non ('% annullato' o 'terminato').
  • Attivo: un processo con stato '% avviato' ma non ('% non riuscito' o '% annullato' o 'finito').

Ho la seguente query SQL per Finished che funziona bene

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'; 

Hai bisogno di aiuto per altre query.

risultato atteso:

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

Grazie in anticipo.

+1

Oracle o mysql? Questi sono due prodotti diversi. Cosa hai fatto fino ad ora? – Shadow

+0

usa nested select può aiutarti a provarlo? –

+0

Non voglio query specifiche per database, quindi ho aggiunto Oracle e mysql. – jitk

risposta

1

La versione per 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 

Fondamentalmente ho messo tutti gli stati per ciascuno jobid a una stringa che si chiama steps. Dopodiché cerco nella stringa se esiste uno stato specifico oppure no. Poiché possono esistere più di uno jobid per tali criteri, utilizzare nuovamente per modificare il risultato in stringa. Nel caso in cui si abbiano 2 lavori completati (con ID 1 e 5), vedrete FINISHED: 1 5

La versione per MySql con esempio SQL Fiddle. È un po 'più lungo perché non abbiamo WITH su 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 
Problemi correlati