2013-08-22 4 views
-1

이 정보를 찾지 못했기 때문에 커뮤니티에 미리 사과드립니다.로그 데이터의 시퀀스를 사용자에게 알맞은 뷰로 정렬하십시오 (FIFO synonim)

적절한보기로 로그 데이터 시퀀스를 사용자에게 정렬하는 데 문제가 있습니다.

기본적으로 모든 데이터는 삽입 (작업 = 1) 및 삭제 (작업 = 3)의 두 가지 방법으로 기록됩니다.

테이블 로그에는 old, new, operation 및 date 열이 있습니다. INSERT시 이전 열이 NULL이고 열이 값을 갖습니다. DELETE에서 old 열이 값을 가져오고 new 열이 NULL입니다.

U 샘플 코드

;with x as (select null old, 'A' new, 1 operation, cast('20130822 12:00:01.100' as datetime) dt 
     union all 
     select null,'B', 1 , '20130822 12:00:01.700' dt 
     union all 
     select 'B',null, 3 , '20130822 12:00:02.100' dt 
     union all 
     select null,'C', 1 , '20130822 12:00:05.700' dt 
     union all 
     select 'C',null, 3 , '20130822 12:00:06.100' dt 
     union all 
     select null,'B', 1 , '20130822 12:00:08.700' dt 
     ) 

I는 다음과 같이해야 얻을 필요가 결과에 볼 수 있습니다

: 나는 XML 경로에 대한 를 통해이를 실행하려고

OLD  NEW  TIME 
     A  22-08-2013 12:00:01 
A|  A|B  22-08-2013 12:00:01 
A|B  A|B|C 22-08-2013 12:00:02 
A|B|C A|C  22-08-2013 12:00:05 
A|C  A  22-08-2013 12:00:06 
A  A|B  22-08-2013 12:00:08 

하지만, 여전히 결과를 얻지 못했습니다. 또한주기가 가능하지 않습니다. 다른 쿼리에 참여할 수있는 하나의 쿼리를 가져와야합니다.

내가보기에, 여기서는 작동 유형과 시간이 적용 되었기 때문에 범위를 확인해야합니다. 누군가 그 문제를 해결하는 방법에 대한 제안을 할 수 있습니까? 감사합니다.

답변

0

이 쿼리는 쉽지만 효과가 없습니다.

;with x(old, new, operation, dt) as (
    select null, 'A', 1, cast('20130822 12:00:01.100' as datetime) union all 
    select null, 'B', 1, '20130822 12:00:01.700' dt union all 
    select 'B', null, 3, '20130822 12:00:02.100' dt union all 
    select null, 'C', 1, '20130822 12:00:05.700' dt union all 
    select 'C', null, 3, '20130822 12:00:06.100' dt union all 
    select null, 'B', 1, '20130822 12:00:08.700' dt 
), y as (
    select x1.dt, isnull(x2.new, x2.old) u 
    from x x1 
    inner join x x2 on x1.dt >= x2.dt 
    group by x1.dt, isnull(x2.new, x2.old) 
    having sum((x2.operation - 2) * (-1)) > 0 
) 

select min(case i when 1 then new end) old 
    , min(case i when 0 then new end) new 
    , min(case i when 0 then dt end) dt 
from (
    select distinct dt 
     , dense_rank() over(order by dt) num 
     , stuff ((
      select '|' + u 
      from y y2 
      where y1.dt = y2.dt 
      for xml path('') 
     ), 1, 1, '') new 
    from y y1 
) t 
cross join (values(0),(1))i(i) 
group by num+i 
having min(case i when 0 then dt end) is not null 
order by dt 
+0

놀라운 !!!! 그리고 더 많은 부서가있을 수 있습니다 ...? – notricky

+0

어쩌면 첫 번째 진술 *을 x as() *를 실제 데이터 쿼리 (10 억 개가 넘는 로그 레코드가있는 테이블에서 다른 많은 기록 테이블과 조인)로 대체했을 때이 쿼리를 어떻게해서든지 최적화 할 수 있습니다. - 실행을 위해 21 초 남았습니다. IO 통계를 보았을 때 - 로그와 다른 테이블에서 2 억 개의 _logical reads_ 때문에 충격을 받았습니다. 그러나 임시 테이블 (@tmp 비슷하게)에 데이터를 놓았을 때 - 정상적으로 작동했습니다. 어떻게 든 a * 연산자는 @tmp 테이블처럼 작동하지 않습니다. 최적화를 위해 무엇을 할 수 있습니까? – notricky

+0

아, 마지막으로 ** 작업 ** 필드를 쿼리 끝에 가져 오는 중 문제가 있습니다 ... – notricky

관련 문제