2015-12-17 11 views
5

Benötigen Sie Hilfe beim Schreiben von SQL-Abfragen, die mehrere Filter für dasselbe Feld einer Tabelle enthalten.SQL-Abfrage zum Abrufen des übergeordneten Elements (Job) ohne angegebene untergeordnete Elemente (Status)

Ich habe 2 Tabellen wie unten gezeigt.

Job Tabelle:

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 

und

Status Tabelle:

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 

Aus diesen zwei Tabellen I für Jobs abzufragen haben mit Staaten abgeschlossen, ABGESAGT, FAILED und ACTIVE wo

  • FERTIG: Ein Job mit dem Status 'Beendet'.
  • ABGEBROCHEN: Ein Job mit dem Status '% Storniert', aber nicht ('Beendet').
  • FEHLGESCHLAGEN: Ein Job mit dem Status '% Failed', aber nicht ('% Canceled' oder 'Finished').
  • Aktiv: Ein Job mit dem Status '% Started', aber nicht ('% Failed' oder '% Canceled' oder 'Finished').

Ich habe die folgende SQL-Abfrage für Finished die

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

Brauchen Sie Hilfe für andere Abfragen gut funktioniert.

Erwarteter Ausgang:

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

Vielen Dank im Voraus.

+1

Oracle oder mysql? Dies sind zwei verschiedene Produkte. Was hast du bis jetzt gemacht? – Shadow

+0

Verwendung geschachtelte Auswahl kann Ihnen helfen, haben Sie versucht? –

+0

Ich möchte keine datenbankspezifische Abfrage, also habe ich Oracle und MySQL hinzugefügt. – jitk

Antwort

1

Die Version für Oracle ist:

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 

Grundsätzlich habe ich alle Status für jeden jobid zu einer Zeichenfolge, die steps genannt wird. Danach suche ich in einer Zeichenfolge, ob ein bestimmter Status existiert oder nicht. Da es für solche Kriterien mehr als einen jobid geben kann, verwende ich erneut listagg, um das Ergebnis in string zu ändern. Wenn Sie zwei abgeschlossene Jobs (mit ID 1 und 5) haben, sehen Sie FINISHED: 1 5

Die Version für MySql mit Beispiel SQL Fiddle. Es ist ein bisschen länger, da wir WITH auf MySql nicht haben.

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 
Verwandte Themen