2017-10-13 21 views
0

저는 SQL과 데이터베이스 구조에 비교적 익숙하지 않으며 이에 대해 가장 좋은 방법이 무엇인지에 대해 질문합니다.SQL : 특정 날짜의 스냅 샷 개요를 생성하기 위해 히스토리 테이블을 가장 잘 쿼리하는 방법

가끔 특정 날짜의 스냅 샷으로 변환해야하는 객체의 변경 기록 데이터가 있습니다. 데이터의

예 :

ID  Value  UpdateDate 

1   4   2017-01-01 
2   4   2017-01-03 
3   4   2017-01-03 
1   7   2017-01-04 
2   5   2017-01-08 
3   5   2017-01-10 
2   8   2017-01-11 

나는 주어진 일에 모든 객체의 전체 개요의 스냅 샷을 생성 할 수 있어야합니다. 예 :

Current Date: 2017-01-01    |  Current Date: 2017-01-04 
ID  Value  LastUpdateDate | ID  Value  LastUpdateDate    
             | 
1   4   2017-01-01  | 1   7   2017-01-04 
             | 2   4   2017-01-03 
             | 3   4   2017-01-03 
__________________________________________________________________________________ 
             | 
    Current Date: 2017-01-08    |  Current Date: 2017-01-12 
ID  Value  LastUpdateDate | ID  Value  LastUpdateDate    
             | 
1   7   2017-01-04  | 1   7   2017-01-04 
2   5   2017-01-08  | 1   8   2017-01-10 
3   4   2017-01-03  | 1   5   2017-01-11 

다음 SQL 쿼리를 생성하여이 테이블을 생성했습니다. 그러나 이것이 이것이 가장 효율적인 방법인지 궁금합니다. 사실 내 테이블은 매우 크며 개체 유형 당 200,000-300,000 개의 고유 한 개체가 매일 수천 개씩 업데이트됩니다 (개체별로 다르지는 않지만 매일 수천 개의 행이 기록 테이블에 추가되므로 크기가 커집니다). 빨리).

SQL 쿼리 :

SELECT * INTO @CurrentOverviewTableName 
FROM @HistoryTableName 
INNER JOIN (
    SELECT ID AS ID_T, MAX(LastUpdateDate) AS LastUpdateDate 
    FROM @HistoryTableName 
    WHERE LastUpdateDate <= @OverviewDate 
    GROUP BY ID 
) ts 
ON [email protected] = ts.ID_T AND @HistoryTableName.LastUpdateDate = ts.LastUpdateDate_T; 

후 나는 예를 들어이 얻을 : 그들은 중복있는 한

ID  Value  LastUpdateDate  ID_T  LastUpdateDate_T 

1   4   2017-01-01   1   2017-01-01 
2   4   2017-01-03   2   2017-01-03 
3   4   2017-01-03   3   2017-01-03 

은 내가 필요한 것을 얻기 위해 마지막 두 개의 열을 놓습니다. 다시 말하지만,이 방법이 최선의 방법인지 궁금해합니다.

저는 Azure SQL DB로 작업하고 있습니다.

답변

0

귀하의 방법은 상관이 없습니다. 대신 SELECT *을 사용, 열을 삭제하려면 원하는 열을 나열 할 수없는 경우

SELECT * 
INTO @CurrentOverviewTableName 
FROM (SELECT ht.*, 
      MAX(LastUpdateDate) OVER (PARTITION BY id) AS max_LastUpdateDate 
     FROM @HistoryTableName ht 
    ) ht 
WHERE max_LastUpdateDate = LastUpdateDate; 

: 나는 윈도우 기능을 사용할 수 있습니다. 당신도 그렇게하지 않으려면, WHERE 절에 조건을 이동 :

SELECT ht.* 
INTO @CurrentOverviewTableName 
FROM @HistoryTableName ht 
WHERE ht.LastUpdateDate = (SELECT MAX(h2.LastUpdateDate) 
          FROM @CurrentOverviewTableName ht2 
          WHERE ht2.id = ht.id 
         ); 
0

을 그들은 당신이 아래의 코드를 사용할 수있는 값에 돌아 가지 않는다 가정. 값에서 회귀하는 옵션을 원할 경우 표의 기본 키 (identity key)가 필요하며 최대 ID를 대신 사용하십시오. 하위 쿼리가 약간 변경됩니다. 기본 키를 사용하면 ID와 값이라는 두 값 대신 기본 키만 사용하여 하위 쿼리를 더 쉽게 되돌릴 수 있습니다. 아래를 참조하십시오.

--change the date for a different time period 
DECLARE @updateDate date = '2017-01-12' 
DECLARE @temp TABLE (ID int, Value int, updateDate date) 

INSERT INTO @temp VALUES 
(1, 4, '2017-01-01') 
,(2, 4, '2017-01-03') 
,(3, 4, '2017-01-03') 
,(1, 7, '2017-01-04') 
,(2, 5, '2017-01-08') 
,(3, 5, '2017-01-10') 
,(2, 8, '2017-01-11') 

SELECT dT.* 
     ,(SELECT T2.updateDate 
     FROM @temp T2 
     WHERE T2.ID = dT.Id AND T2.Value = dT.MaxValue) [LastUpdateDate] 
    FROM (
     SELECT ID, MAX(Value) MaxValue 
      FROM @temp T 
     WHERE T.updateDate <= @updateDate 
     GROUP By ID 
     ) AS dT