3

最近、EDW テーブルから Dim テーブルを設定する必要があるプロジェクトに取り組んでいます。

EDW テーブルは、履歴データを保持するタイプ II です。ソースが複数の EDW テーブルである場合もあれば、(属性で) 複数レベルのピボットを備えた単一のテーブルである場合もある Dim テーブルをロードする場合。

つまり、10 個のレコードが存在することになります。Dim で単一の行を作成するために、domain_code でピボットする必要がある属性ごとに 1 つです。これらの 10 個のレコードのうち、domain_code は同じで sub_domain_code が異なる属性がいくつかあるため、サブドメイン コードをさらにピボットする必要があります。

元:

ドメイン コードを取得した場合: 01,02, 03 => これはドメイン コードのストレート ピボットです。また、ドメイン コード: 10、サブドメイン コード / バージョンを 2006,2007,2008,2009 とします。

つまり、上記の属性を持つソース テーブルを 2 つに分割する必要があります => 1 つはドメイン コード用、もう 1 つは domain_code + バージョン用です。

ここまでは順調ですね。

Dim テーブルをロードする場合:

ディメンションの設計仕様 (元々はサード パーティによって作成されたもの) によると、彼らが求めているのは次のとおりです。

EDW(属性)のすべての変更に対して、関連するすべてのレコード(そのNKの)をアセンブルする必要があります。つまり、現在の他の属性値を持つ新しいレコードを意味します=>それらを処理して、新しいdimレコードを作成し、挿入します。

つまり、1 つの抽出に更新された 100 レコード (NK ごとに 1 つ) が含まれている場合、100 + (100*9) レコードを集めて、dim テーブルを挿入/更新する必要があります。このアプローチの良さ。

私がやろうとした他の方法は、NKが最近のレコード(変更されていない属性)の値を取得し、それを挿入して現在のレコードを更新するために、dimテーブルを検索することです。

1 つの属性の変更に対してソース側でレコードを組み立てるか、dim テーブルの最近のレコードを調べて処理するより良いアプローチは何でしょうか。

これが意味をなさない場合は、さらに詳しく説明したいと思います。

ありがとう

テーブルのモデルはこちら

代替テキスト http://img96.imageshack.us/img96/1203/modelzp.jpg

4

1 に答える 1

2

この例を見てください。

それは比較的簡単なはずです。

ルールに従ってベース データをピボットします。

非正規化された「行」の変更時間を決定します

三角形の結合を作成して、各期間の開始と終了を決定します (これをスナップショットと呼んでいます)。

次に、それらのウィンドウをベース データに結合して、その時点でのデータの状態を判断します (ピボットはこの時点で実際に完了しています)。

ウィンドウ メカニズムを確認する必要があるかもしれないと思います - 正しいデータを返していますが、ウィンドウ オーバーラップ ロジックが私に見える方法が好きではありません - かなり小さいわけではありません - 境界条件が心配です.

-- SO3014289

CREATE TABLE #src (
    key1 varchar(4) NOT NULL
    ,key2 varchar(3) NOT NULL
    ,key3 varchar(3) NOT NULL
    ,AttribCode int NOT NULL
    ,AttribSubCode varchar(2)
    ,Value varchar(10) NOT NULL
    ,[Start] date NOT NULL
    ,[End] date NOT NULL
)

INSERT INTO #src VALUES
('9750', 'C04', '789', 1, NULL, 'AAA', '1/1/2000', '12/31/9999')
,('9750', 'C04', '789', 2, NULL, 'BBB', '1/1/2000', '12/31/9999')
,('9750', 'C04', '789', 3, 'V1', 'XXXX', '1/1/2000', '12/31/9999')
,('9750', 'C04', '789', 3, 'V2', 'YYYY', '1/1/2000', '1/2/2000')
,('9750', 'C04', '789', 3, 'V2', 'YYYYY', '1/2/2000', '12/31/9999')

;WITH basedata AS (
    SELECT key1 + '-' + key2 + '-' + key3 AS NK
    ,CASE WHEN AttribCode = 1 THEN Value ELSE NULL END AS COL1
    ,CASE WHEN AttribCode = 2 THEN Value ELSE NULL END AS COL2
    ,CASE WHEN AttribCode = 3 AND AttribSubCode = 'V1' THEN Value ELSE NULL END AS COL3
    ,CASE WHEN AttribCode = 3 AND AttribSubCode = 'V2' THEN Value ELSE NULL END AS COL4
    ,[Start]
    ,[End]
    FROM #src
)
,ChangeTimes AS (
    SELECT NK, [Start] AS Dt
    FROM basedata
    UNION 
    SELECT NK, [End] AS Dt
    FROM basedata
)
,Snapshots as (
    SELECT s.NK, s.Dt AS [Start], MIN(e.Dt) AS [End]
    FROM ChangeTimes AS s
    INNER JOIN ChangeTimes AS e
        ON e.NK = s.NK
        AND e.Dt > s.Dt
    GROUP BY s.NK, s.Dt
)
SELECT Snapshots.NK
    ,MAX(COL1) AS COL1
    ,MAX(COL2) AS COL2
    ,MAX(COL3) AS COL3
    ,MAX(COL4) AS COL4
    ,Snapshots.[Start]
    ,Snapshots.[End]
FROM Snapshots
INNER JOIN basedata
    ON basedata.NK = Snapshots.NK
    AND NOT (basedata.[End] <= Snapshots.[Start] OR basedata.[Start] >= Snapshots.[End])
GROUP BY Snapshots.NK
    ,Snapshots.[Start]
    ,Snapshots.[End]
于 2010-06-18T17:29:34.387 に答える