1

Trip_aud と Event_aud という 2 つの監査テーブルがあります。それらは Envers で作成されましたが、SQL でクエリを実行しています。これらは基本的にドメイン テーブルと同じですが、変更があるたびにリビジョン値が増加し、監査テーブルにいくつかのタプルが挿入されます。

Trip が特定のステータス ( PLANNING-> EXECUTING) から変更されると、現在のリビジョンを保存するので、その後、実行されたもの (出発時間など) と計画されたものを比較できます。これらのイベント (出発、停止、待機中...) は、Trip へのポインターと共に Event に格納されます。イベントも監査されます。

Envers は CVS システムのように機能します: 特定のリビジョンで何らかの要素を照会すると、特定のリビジョンよりも小さい最大リビジョンを持つタプルが検索されます。私が興味を持っているリビジョンは、状態が変化したときに保存される Trip のものです。特定のリビジョンの旅行からすべてのイベントを選択するにはどうすればよいですか?

テーブルの外観は次のとおりです。org_revステータスが変更される出張リビジョンです。

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   |

リビジョン 3 の旅行とイベントが必要な場合は、

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   |

リビジョン 44 で、計画が終了した時点で、

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   |

計画と実行を比較するために次のクエリを作成しましたが、何も返されません! EVENT_AUD で自己結合を行い、リビジョンの順序のみが異なるタプルの重複を排除し、トリップ時revよりも小さい最大値を選択しようとしますorg_rev

 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}

t.org_rev不思議なことに、 44に置き換えるとうまくいきます。私は何を間違っていますか?

助けてくれてありがとう!

メタ: CSV、XML、INCLUDE INTO などで、私が求めている SQL を人々がテストできるように、データベースの例を少し提供することは期待されていますか? 質問に添付するにはどうすればよいですか?

4

1 に答える 1

1

トリップIDでもea1とea2に参加する必要があると思います。これは、この方法でmaxがすべてのイベントの最大回転数を与えるためです。この結合は、eventとevent_audの間にもありません。相関サブクエリのニーズ

where ea1.trip_id = t.id

アップデート:

(select ...)で計画されたロジックを理解していなかったので、存在しないように変更しました:

 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

完全なクエリはSQLフィドルにあります

于 2012-03-30T10:39:12.763 に答える