выбрать максимальное значение во внутреннем запросе <другое во внешнем запросе - PullRequest
1 голос
/ 30 марта 2012

У меня есть две таблицы аудита: Trip_aud и Event_aud. Они были созданы в Envers, но я запрашиваю их с помощью SQL. Они в основном такие же, как таблицы доменов, за исключением значения ревизии, которое увеличивается каждый раз, когда происходит изменение, и некоторый кортеж вставляется в таблицу аудита.

Когда Trip отключается от определенного состояния (PLANNING -> EXECUTING), я сохраняю его текущую ревизию, поэтому после этого я могу сравнить то, что было выполнено (скажем, время выхода) с тем, что было запланировано. Эти события (уход, остановка, ожидание ...) сохраняются в событии с указателем на отключение. События тоже проверяются.

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, который я запрашиваю? Как мне прикрепить вопрос?

1 Ответ

1 голос
/ 30 марта 2012

Я думаю, что вам нужно присоединиться к ea1 и ea2 и для идентификатора поездки, потому что таким образом max дает максимальное число оборотов для всех событий.Это соединение также отсутствует между event и event_aud.Связанные потребности подзапроса

where ea1.trip_id = t.id

ОБНОВЛЕНИЕ:

Я не понял логику в запланированном в (выберите ...), поэтому я изменил ее на не существует:

 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

...