2012-03-29 3 views
1

Trip_aud 및 Event_aud의 두 감사 테이블이 있습니다. 그것들은 Envers에서 만들어졌지만 SQL로 쿼리하고 있습니다. 기본적으로 도메인 테이블과 동일하지만 변경 사항이있을 때마다 증가하고 일부 튜플이 감사 테이블에 삽입되는 개정 값은 예외입니다.내부 쿼리의 최대 값 선택 <외부 쿼리의 다른 값

트립이 특정 상태 (->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 | 

I 개정 3에서 여행 및 이벤트를 원하는 경우에, 나는 개정 44

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 | 

를 얻을, 내가 다음을 한

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에서 자체 조인을 만들고 수정 순서가 다른 튜플 중복을 제거하고 트립시 최대 revorg_rev 미만으로 선택하려고 시도합니다. 나는 44 t.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} 

이상하게도, 그것을 작동합니다! 내가 도대체 ​​뭘 잘못하고있는 겁니까?

도움 주셔서 감사합니다.

메타 : CSV, XML, INCLUDE INTO 등에서 약간의 데이터베이스 예제를 제공 할 예정입니까? 그렇다면 사람들이 내가 원하는 SQL을 테스트 할 수 있습니까? 어떻게 질문에 붙일 수 있습니까?

+0

META 대답 : 예, 데이터를 작성하기 위해 SQL을 제공하면 많은 도움이됩니다. 질문을 편집하거나 다른 좋은 방법은 코드를 "요지"에 붙여 넣는 것입니다 (https://gist.github.com/). 그런 다음 요점을 질문에 넣으십시오. – joelparkerhenderson

답변

1

여행 ID에 ea1과 ea2에 가입해야한다고 생각합니다.이 방법은 모든 이벤트에 대해 최대 회전 수를 제공하기 때문에. 이 조인은 event와 event_aud 사이에서도 누락됩니다. (... 선택)

내가 년 계획의 논리를 이해하지 못했다 그래서 나는 그렇지 존재로 변경 : 상관 관계 서브 쿼리는

where ea1.trip_id = t.id 

UPDATE 필요

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 

전체 쿼리입니다 at Sql Fiddle