我的努力有必要吗?我的方法是否创造了一个合适的主键



我正在尝试从没有主键的现有数据仓库表(OldTable(创建维度表(NewTable(。

OldTable[IdentifierCode]中保存不同的值,其他值在它周围重复。我还需要调用3个函数来添加报告上下文。

我希望IdentifierCode_ID是INT列,因为[IdentifierCode]列是VARCHAR(6)

我的问题是:使用ROW_NUMBER()(如下所示(是否会产生一个适当的唯一值?

我担心的是,如果插入其他行以修正遗漏的代码,则活动表上的行顺序可能会更改。

编辑OldTable总共有500k行,使用WHERE子句过滤时有227k行

SELECT
ROW_NUMBER() OVER (ORDER BY LoadDate, StartDate, Product, IdentifierCode) AS IdentifierCode_ID,
LoadDate, 
StartDate,
EndDate,
Product,
IdentifierCode,
OtherField1, OtherField2, OtherField3, OtherField4,
Function1, Function2, Function3
INTO 
NewTable
FROM 
OldTable
WHERE
GETDATE() BETWEEN StartDate AND EndDate

首先,除非您加载一次数据,然后再也不接触它,或者在每次加载新的日期范围之前截断NewTable,否则您的方法将不起作用。ROW_NUMBER将在1重新启动并违反主键。

即使您正在截断表或只加载一次,仍然有更好的方法。将IdentifierCode_ID指定为"标识"列,SQL将为您处理它。如果类型为INT并且设置了IDENTITY,则在插入新行时,SQL将自动在最后一个值上加1,您甚至不必分配它!

CREATE TABLE dbo.NewTable(
[IdentifierCode_ID] int IDENTITY(1,1) NOT NULL,
[IdentifierCode] VARCHAR(6) NOT NULL,
...

此外,如果意外地为后续加载选择了一个重叠的日期范围,并且OldTable中的值发生了变化,请确保考虑到您将要做什么——例如,向WHERE子句添加一个限制,以从插入中排除现有的IdentifierCode值,并添加第二个查询,以更新具有不同LoadDateStartDate等的现有IdentifierCode值。

...
AND NOT EXISTS (SELECT * FROM NewTable as N WHERE N.IdentifierCode = OldTable.IdentifierCode)

为了更新已更改的现有行,可以执行INNER JOIN以仅选择现有行,并为已更改的行执行WHERE子句。

UPDATE NewTable
SET LoadDate = O.LoadDate, StartDate = O.StartDate, ... --don't forget to recalculate the functions!
FROM NewTable as N INNER JOIN OldTable as O on N.IdentifierCode = O.IdentifierCode
WHERE GETDATE() between O.StartDate and O.EndDate
AND NOT (N.StartDate = O.StartDate and N.EndDate = O.EndDate ... )

最新更新