2012-03-29 9 views
1

Ich habe zwei Auditing-Tabellen: Trip_aud und Event_aud. Sie wurden in Envers erstellt, aber ich frage sie mit SQL ab. Sie sind im Grunde die gleichen wie die Domain-Tabellen, mit Ausnahme eines Revisionswerts, der bei jeder Änderung inkrementiert wird und ein Tupel in eine Auditing-Tabelle eingefügt wird.Wählen Sie den maximalen Wert in der inneren Abfrage <ein anderer in einer äußeren Abfrage

Wenn Trip sich von einem bestimmten Status (PLANNING ->EXECUTING) ändert, speichere ich seine aktuelle Revision, danach kann ich vergleichen was ausgeführt wurde (sagen wir Zeit) mit was geplant war. Diese Ereignisse (Verlassen, Anhalten, Warten ...) werden im Event mit einem Zeiger auf Trip gespeichert. Auch Veranstaltungen werden auditiert.

Envers funktioniert wie ein CVS-System: Wenn ich nach einem Element bei einer bestimmten Revision frage, sucht es nach dem Tupel, das die maximale Revision weniger als die angegebene Revision hat. Die Revision, an der ich interessiert bin, ist diejenige in Trip, die gespeichert wird, wenn sie ihren Status ändert. Wie kann ich alle Ereignisse einer Reise in einer bestimmten Revision auswählen?

So sehen die Tabellen aus. org_rev ist die Reiseversion, in der sich der Status ändert.

Trip_aud 
id | rev | status | org_rev | other columns... 
----|-----|----------|---------|--------------- 
1 | 1 |CREATED | NULL | 
1 | 2 |OPTIMIZING| NULL | 
1 | 3 |PLANNED | NULL | 
1 | ... | ... | NULL | 
1 | 44 |EXECUTING | 44 | 
1 | 58 |FINISHED | 44 | 

Event_aud 
id | trip_id | rev | start_time | other columns... 
----|---------|-----|------------|--------------- 
1 | 1 | 1 | 02:35:12 | 
2 | 1 | 1 | 03:14:84 | 
3 | 1 | 1 | 12:31:02 | 
1 | 1 | 2 | 04:00:00 | 
2 | 1 | 5 | 03:00:15 | 
2 | 1 | 10 | 05:49:59 | 
1 | 1 | 40 | 06:00:00 | 
1 | 1 | 58 | 06:07:39 | 

Wenn ich die Reise und Veranstaltungen auf Revision 3 wollen, bekomme ich

Trip_aud 
id | rev | status | org_rev | other columns... 
----|-----|----------|---------|--------------- 
1 | 3 |PLANNED | NULL | ... 

Event_aud 
id | trip_id | rev | start_time | other columns... 
----|---------|-----|------------|--------------- 
1 | 1 | 2 | 04:00:00 | 
2 | 1 | 1 | 03:14:84 | 
3 | 1 | 1 | 12:31:02 | 

In Revision 44, bei der Planung fertig war, ist es

Trip_aud 
id | rev | status | org_rev | other columns... 
----|-----|----------|---------|--------------- 
1 | 44 |EXECUTING | 44 | 

Event_aud 
id | trip_id | rev | start_time | other columns... 
----|---------|-----|------------|--------------- 
1 | 1 | 40 | 06:00:00 | 
2 | 1 | 10 | 05:49:59 | 
3 | 1 | 1 | 12:31:02 | 

ich gemacht habe, die folgende Abfrage zum Vergleich der Planung und ausgeführt, aber es gibt nichts zurück! Es macht einen Self-Join in EVENT_AUD, entfernt Tupel-Duplikate, die sich nur in ihrer Revisionsreihenfolge unterscheiden, und versucht, das Maximum rev kleiner als org_rev bei Trip auszuwählen. Merkwürdiger

select t.id, planned.start_time, realized.start_time 
from 
    TRIP t 
    inner join EVENT realized on realized.trip_id = t.id 
    inner join EVENT_AUD planned on planned.id = realized.id 
where 
    planned.id in 
    (
     select ea1.id 
     from 
      EVENT_AUD ea1 
      inner join EVENT_AUD ea2 on ea1.id = ea2.id 
     where 
      ea1.rev > ea2.rev 
     group by ea1.id 
     having max(ea1.rev) < t.org_rev 
    ) 
    and t.id = {something given outside} 

, wenn ich t.org_rev mit 44 ersetzen, es funktioniert! Was mache ich falsch?

Danke für jede Hilfe!

META: soll es ein kleines Datenbankbeispiel in CSV, XML, INCLUDE INTOs oder was auch immer geben, also können Leute das SQL prüfen, nach dem ich frage? Wie kann ich die Frage anhängen?

+0

META Antwort: Ja, es hilft eine Menge, wenn Sie die SQL zur Verfügung stellen, um Ihre Daten zu erstellen. Sie können Ihre Frage bearbeiten, oder Sie können Ihren Code in ein "gist" einfügen: https://gist.github.com/ und dann die URL in die Frage einfügen. – joelparkerhenderson

Antwort

1

Ich denke, dass Sie auch auf Trip-ID ea1 und ea2 beitreten müssen, weil auf diese Weise Max maximale Drehzahl für alle Ereignisse gibt. Dieser Join fehlt auch zwischen event und event_aud. Korrelierte Unterabfrage muss

where ea1.trip_id = t.id 

UPDATE:

Ich habe nicht Logik verstehen in geplant in (wählen ...), so habe ich es nicht vorhanden ist:

select t.id TripID, 
     planned.id pid, 
     planned.rev, 
     planned.start_time pst, 
     realized.start_time rst 
from 
    TRIP t 
    inner join EVENT realized 
     on realized.trip_id = t.id 
    inner join EVENT_AUD planned 
     on planned.id = realized.id 
      and realized.trip_id = planned.trip_id 
     -- Eliminate higher revisions 
      and planned.rev < t.org_rev 
where not exists (select null 
      from event_aud ea 
      where ea.trip_id = planned.trip_id 
       and ea.id = planned.id 
     -- Eliminate higher revisions 
       and ea.rev < t.org_rev 
     -- If there is higher revision than current not exists evaluates to false 
       and ea.rev > planned.rev) 
    and t.id = 1 
order by 1, 2 

Voll Abfrage um Sql Fiddle

Verwandte Themen