2017-10-13 3 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クエリを作成してこれらのテーブルを作成しました。しかし、これを実行するのに最も効率的な方法であるかどうか疑問に思っていましたか?現実の私のテーブルは、オブジェクトごとに数千の更新(オブジェクトごとではなく、数千の行が毎日履歴テーブルに追加されるので、サイズがかなり大きくなっています。早く)。

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 

彼らは重複しているように私は私が必要なものを得るために、最後の2つの列をドロップします。繰り返しますが、これはうまくいきますが、それを行う最良の方法であるかどうか疑問に思っていますか?

私は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

を、彼らはあなたが以下のコードを使用することができます値に戻っていないと仮定。 Valueで回帰するオプションが必要な場合は、表の主キーとしてID列が必要で、代わりに最大IDを使用する必要があります。サブクエリはわずかに変更されます。プライマリキーは、IDと値の2つの値の代わりにプライマリキーだけを使用して、サブクエリを簡単に戻します。下記参照。

--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 
関連する問題