同じデータを格納する複数のレイヤーを持つデータ ウェアハウスを構築しています。中間層の 1 つのデータはすべて、タイプ 2 の緩やかに変化するディメンションであるかのように、開始日と終了日でバージョン管理されます。これらのテーブルをクエリすると、問題が発生します。通常、テーブルにはクエリよりも多くの列があるため、クエリ内の隣接するバージョンの開始日と終了日は異なりますが、それ以外は同一です。これらのバージョンを組み合わせて、テーブルの行が変更された日付ではなく、クエリの列が変更された日付を表示したいと考えています。
ほとんど機能するSQLがいくつかあります:
create table versions
(id int
, name varchar(100) Not null
, RowStartDate datetime Not null
, RowEndDate datetime Not null
, primary key (id,RowStartDate)
, check (RowStartDate < RowEndDate));
insert into versions values
(1,'A','2014-01-01','9999-12-31')
,(2,'B','2014-01-01','2014-12-31')
,(2,'B','2014-12-31','9999-12-31')
,(3,'C','2014-01-01','2014-12-31')
,(3,'CC','2014-12-31','2015-12-31')
,(3,'CC','2015-12-31','9999-12-31')
,(4,'D','2014-01-01','2014-12-31')
,(4,'DD','2014-12-31','2015-12-31')
,(4,'DD','2015-12-31','2016-12-31')
,(4,'D','2016-12-31','9999-12-31')
,(5,'E','2014-01-01','2014-12-31')
,(5,'E','2014-12-31','2015-12-31')
,(5,'E','2015-12-31','2016-12-31')
,(5,'E','2016-12-31','2017-12-31')
,(5,'E','2017-12-31','9999-12-31')
;
WITH CTE_detect_duplicates AS (SELECT [id]
,[name]
,[RowStartDate]
,[RowEndDate]
,LAST_VALUE(RowEndDate) OVER (PARTITION BY id, name ORDER BY RowStartDate, RowEndDate ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) as LastEndDate
,rank() OVER (PARTITION BY id, name ORDER BY RowStartDate, RowEndDate) as duplicateNumber
FROM versions
)
SELECT [id]
,[name]
,[RowStartDate]
,LastEndDate as RowEndDate
FROM CTE_detect_duplicates
WHERE duplicateNumber = 1
ここでの問題は、3 つの行が必要な場合に、ID "4" に対して 2 つの行を返すことです。実際:
ID名 RowStartDate RowEndDate 4 D 2014-01-01 00:00:00.000 9999-12-31 00:00:00.000 4 DD 2014-12-31 00:00:00.000 2016-12-31 00:00:00.000希望:
ID名 RowStartDate RowEndDate 4 日 2014-01-01 00:00:00.000 2014-12-31 00:00:00.000 4 DD 2014-12-31 00:00:00.000 2016-12-31 00:00:00.000 4 日 2016-12-31 00:00:00.000 9999-12-31 00:00:00.000値 DD が正しい期間に対して値 D が正しくないため、my クエリの最初の行 (4,'D') のバージョン日付が正しくありません。
純粋な SQL またはインラインのテーブル値関数でこれらの重複を削除できるようにしたい (これを行う複数ステートメントのテーブル値関数を作成するジェネレーターがありますが、結果の関数のパフォーマンスが低下します)。誰にもアイデアはありますか?