문제

내 기억이 실패하고 있습니다. 트리거를 기반으로 간단한 감사 로그 테이블이 있습니다.

IDint (Identity, PK)
고객 IDint
이름바르 차 (255)
주소바르 차 (255)
감사합니다날짜 시간
감사 코드숯 (1)


다음과 같은 데이터가 있습니다.

ID고객 ID이름주소감사합니다감사 코드 1  123        단발123 인터넷 웨이2009-07-17 13:18:06.353 2  123        단발123 인터넷 웨이2009-07-17 13:19:02.117 3  123        실내 변기123 인터넷 웨이2009-07-17 13:36:03.517 4  123        단발123 내 편집 방법2009-07-17 13:36:08.050 5  100        아놀드100 Skynet Way2009-07-17 13:36:18.607 6  100        니키100 스타 웨이2009-07-17 13:36:25.920 7  110        블론디110 다른 방법2009-07-17 13:36:42.313 8  113        출격113 또 다른 방법2009-07-17 13:36:57.627


시작 시간과 종료 시간 사이에 가장 많은 최신 레코드를 얻는 효율적인 선정 진술은 무엇입니까? 참고 : INSERT, D 삭제 용 D 및 업데이트 용 U입니다.

감사 테이블에 놓친 것이 있습니까? 다음 단계는 변경 사항 만 기록하는 감사 테이블을 만드는 것입니다. 그러나 주어진 시간 프레임에 대한 최신 레코드를 추출 할 수 있습니다. 내 삶을 위해 검색 엔진에서 쉽게 찾을 수 없습니다. 링크도 작동합니다. 도와 주셔서 감사합니다.

도움이 되었습니까?

해결책

감사 기록을 유지하는 또 다른 (더 나은?) 방법은 AuditDateTime 및 AuditCode 열이 아닌 'startDate'및 'EndDate'열을 사용하는 것입니다. 이것은 종종 데이터웨어 하우스에서 유형 2 변경 (새로운 버전의 행)을 추적하는 방법입니다.

이렇게하면 현재 행을 직접 선택할 수 있으며 (EndDate가 NULL 인 경우) 업데이트를 인서트 또는 삭제와 다르게 처리 할 필요가 없습니다. 단순히 세 가지 경우가 있습니다.

  • 삽입 : 시작 날짜 및 null 종료 날짜와 함께 전체 행을 복사하십시오.
  • 삭제 : 기존 현재 행의 종료 날짜 설정 (EndDate is null)
  • 업데이트 : 삭제 한 다음 삽입하십시오

당신의 선택은 단순히 다음과 같습니다.

select * from AuditTable where endDate is NULL

어쨌든, 여기 기존 스키마에 대한 내 쿼리가 있습니다.

declare @from datetime
declare @to datetime

select b.* from (
  select
    customerId
    max(auditdatetime) 'auditDateTime'
  from
    AuditTable
  where
    auditcode in ('I', 'U')
    and auditdatetime between @from and @to
  group by customerId
  having 
    /* rely on "current" being defined as INSERTS > DELETES */
    sum(case when auditcode = 'I' then 1 else 0 end) > 
    sum(case when auditcode = 'D' then 1 else 0 end)
) a
cross apply(
  select top 1 customerId, name, address, auditdateTime
  from AuditTable
  where auditdatetime = a.auditdatetime and customerId = a.customerId
) b

참조

데이터웨어 하우스의 침대 시트,하지만 유형 2 변경에 대한 좋은 섹션이 있습니다 (추적하고 싶은 내용)

MSDN 페이지 on 데이터웨어 하우징

다른 팁

좋아, 감사 로그 테이블에 대한 몇 가지.

대부분의 응용 프로그램의 경우 감사 테이블이 삽입시 매우 빠르게 진행되기를 원합니다.

감사 로그가 진단 또는 매우 불규칙한 감사 이유에 대한 경우 가장 빠른 삽입 기준은 삽입 시간에 물리적으로 주문하는 것입니다.

그리고 이것은 감사 시간을 클러스터 된 인덱스의 첫 번째 열 (예 :

create unique clustered index idx_mytable on mytable(AuditDateTime, ID)

이를 통해 AuditDateMe O (log n) 및 O (1) 삽입시 매우 효율적인 선택 쿼리가 가능합니다.

고객마다 감사 테이블을 찾으려면 타협해야합니다.

(CustomerID, AuditDateTime)에 비 클러스터 된 인덱스를 추가 할 수 있습니다. 이는 커스토어 당 감사 기록의 O (log n) 조회를 허용 할 수 있지만 비용은 삽입시 비 클러스터 된 색인의 유지 보수가 될 것입니다. 로그 N) 반대로.

그러나 삽입 시간 페널티는 CustomerID에 대한 색인이 없으면 지불 해야하는 테이블 스캔 (즉, O (N) 시간 복잡성 비용)보다 바람직 할 수 있으며 이는 정기적 인 쿼리입니다. 불규칙한 쿼리에 대한 작문 프로세스의 테이블을 잠그는 O (n) 조회는 작가를 차단할 수 있으므로 독자가 커밋을 차단하지 않을 것이라는 보장을 보장하면 작가의 관심사가 약간 느려집니다. 독자는 양호한 색인이 부족하여 스캔을 테이블 스캔해야하기 때문에 ....


추가 : 주어진 기간으로 제한하려는 경우 가장 중요한 것은 무엇보다도 AuditDateTime의 색인입니다. AuditDateTime 순서로 삽입 할 때 클러스터링하십시오. 이것은 처음부터 쿼리를 효율적으로 만들기 위해 할 수있는 가장 큰 일입니다.

다음으로, 주어진 시간대 내에 모든 CustomerID에 대한 최신 업데이트를 찾고 있다면 삽입 날짜로 제한된 데이터를 완전히 스캔해야합니다.

감사 테이블의 범위간에 하위 쿼리를 수행해야합니다.

select CustomerID, max(AuditDateTime) MaxAuditDateTime 
from AuditTrail 
where AuditDateTime >= @begin and Audit DateTime <= @end

그런 다음이를 선택한 쿼리에 통합하십시오 (예 :).

select AuditTrail.* from AuditTrail
inner join 
    (select CustomerID, max(AuditDateTime) MaxAuditDateTime 
     from AuditTrail 
     where AuditDateTime >= @begin and Audit DateTime <= @end
    ) filtration
    on filtration.CustomerID = AuditTrail.CustomerID and 
       filtration.AuditDateTime = AuditTrail.AuditDateTime

다른 접근법은 하위 선택을 사용하는 것입니다

select a.ID
       , a.CustomerID 
       , a.Name
       , a.Address
       , a.AuditDateTime
       , a.AuditCode
from   myauditlogtable a,
       (select s.id as maxid,max(s.AuditDateTime) 
                 from myauditlogtable as s 
                 group by maxid) 
        as subq
where subq.maxid=a.id;

시작 및 종료 시간? 예를 들어 오전 1시에서 오전 3시 사이
또는 시작 및 종료 날짜 시간? 예 : 2009-07-17 13:36 ~ 2009-07-18 13:36

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top