我正在构建一个具有多层存储相同数据的数据仓库。中间层中的所有数据都使用开始和结束日期进行版本化,就好像它是第 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
这里的问题是它返回两行 id "4",而需要三行。实际的:
id 名称 RowStartDate RowEndDate 4 天 2014-01-01 00:00:00.000 9999-12-31 00:00:00.000 4 日 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 日 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 不正确,因此我的查询的第一行 (4,'D') 上的版本日期不正确。
我希望能够在纯 SQL 或内联表值函数中删除这些重复项(我有一个生成器,可以创建执行此操作的多语句表值函数,但生成的函数性能不佳)。有没有人有任何想法?