1

我有两个审计表:Trip_aud 和 Event_aud。它们是在 Envers 中创建的,但我使用 SQL 查询它们。它们与域表基本相同,除了每次更改时都会增加一个修订值,并且在审计表中插入一些元组。

当 Trip 从某个状态(PLANNING-> EXECUTING)发生变化时,我会存储它的当前修订版,因此之后我可以将执行的内容(例如,离开时间)与计划的内容进行比较。这些事件(离开、停止、等待......)存储在 Event 中,并带有指向 Trip 的指针。事件也被审计。

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 替换,它可以工作!我究竟做错了什么?

谢谢你的帮助!

META:是否希望以 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 Fiddle

于 2012-03-30T10:39:12.763 回答