Sql Server将自然密钥转换为代理密钥
我试图找到一种方法来转换一些数据上的自然键,我正在将这些数据导入某种代理键 例如: 假设我有一个名为Sql Server将自然密钥转换为代理密钥,sql,sql-server,sql-server-2008-r2,data-warehouse,business-intelligence,Sql,Sql Server,Sql Server 2008 R2,Data Warehouse,Business Intelligence,我试图找到一种方法来转换一些数据上的自然键,我正在将这些数据导入某种代理键 例如: 假设我有一个名为OrderFact的表,其中保存了有关我的订单的所有信息: CREATE TABLE OrderFact ( Id INT IDENTITY PRIMARY KEY ,OrderId INT NOT NULL ,Amount INT NOT NULL ,Cost MONEY NOT NULL ,SaleDate DATE NOT NULL ); GO
OrderFact
的表,其中保存了有关我的订单的所有信息:
CREATE TABLE OrderFact
(
Id INT IDENTITY PRIMARY KEY
,OrderId INT NOT NULL
,Amount INT NOT NULL
,Cost MONEY NOT NULL
,SaleDate DATE NOT NULL
);
GO
INSERT INTO OrderFact (OrderId, Amount, Cost, SaleDate)
VALUES (1, 2, 12.00, '1/1/2012'), (3, 1, 6.00, '12/29/2011'), (4, 5, 1.00, '1/1/2012');
现在,我从一些供应商的POS系统获取所有订单数据,因此我的暂存表如下所示:
CREATE TABLE OrderStaging
(
OrderId INT
,Vendor INT
,Amount INT
,Cost MONEY
,SaleDate DATE
);
GO
INSERT INTO OrderStaging (OrderId, Vendor, Amount, Cost, SaleDate)
VALUES (1, 1, 2, 12.00, '1/1/2012'), (3, 2, 1, 6.00, '12/29/2011'), (4, 1, 5, 1.00, '1/1/2012');
现在我不在乎是谁下订单,但我想跟踪同一供应商当天下的订单,因为它们被算作是一个bulkorder
我对其应用了特殊折扣
是否有一种方法可以构建数据库,以便跟踪哪些订单是批量订单,从而有效地转换
供应商的自然密钥
,SaleDate
进入某种代理键,以便我可以查找OrderFact.Id
对其?我最终创建了一个以代理键为主键,自然键为列的RelatedOrder
表。然后,我创建了一个RelatedOrderMapping
表,用于通过OrderId
将RelatedOrder
映射到事实表。示例(针对SQL Server 2008 R2的T-SQL):
将VendorId添加到OrderFact表中如何?@Asdfg在判断哪些订单属于哪个供应商方面,
VendorId
并不可靠,因此我认为可能更容易将订单分组以防止不一致。您可能需要创建一个新表来映射供应商id并使用它。如果我理解正确,首先,您说要跟踪来自同一供应商的所有订单,但随后您说供应商ID不可靠。这意味着你不可能实现你的目标,因为数据不好。你能更准确地说明你想做什么吗?我没有完整的信息,但在这种情况下,我会添加一个BulkOrderID
列,并根据你拥有的任何业务规则在登台过程中或登台过程结束时填充它。目前尚不清楚这是否是一个报告系统(“暂存”和“事实”表明它是),但通常确定哪些订单是一个批量订单的一部分是订单处理系统所做的,而不是报告系统所做的。但每种情况都不同。
--Create our RelatedOrder table which contains the Natural Key as its columns
CREATE TABLE RelatedOrder
(
Id INT IDENTITY PRIMARY KEY
,VendorId INT NOT NULL
);
GO
--Create our mapping table for linking OrderFact to RelatedOrder
CREATE TABLE RelatedOrderMapping
(
Id INT IDENTITY PRIMARY KEY
,RelatedOrderId INT NOT NULL REFERENCES RelatedOrder (Id)
,OrderFactId INT NOT NULL REFERENCES OrderFact (Id)
,OrderId INT NOT NULL
);
GO
--Insert one instance of each VendorId
INSERT INTO RelatedOrder (VendorId)
SELECT DISTINCT VendorId FROM OrderStaging;
GO
--Create a temp table to hold our output clause
CREATE TABLE #RelatedOrder
(
Id INT IDENTITY PRIMARY KEY
,RelatedOrderId INT NOT NULL REFERENCES RelatedOrder (Id)
,OrderFactId INT NOT NULL REFERENCES OrderFact (Id)
,OrderId INT NOT NULL
);
GO
--Create our precomputed table to speed up the MERGE
CREATE TABLE #OrderStaging
(
OrderId INT NOT NULL
,Amount INT NOT NULL
,Cost MONEY NOT NULL
,SaleDate DATE NOT NULL
,RelatedOrderId INT NOT NULL
);
GO
--Precompute our MERGE statement
INSERT INTO #OrderStaging(OrderId, Amount, Cost, SaleDate, RelatedOrderId)
SELECT OrderId, Amount, Cost, SaleDate, RelatedOrderId
FROM OrderStaging os
JOIN RelatedOrder ro
ON ro.VendorId = os.VendorId
--Insert our data into the fact table and output the result into our #RelatedOrder
MERGE OrderFact AS [Target]
USING #OrderStaging AS [Source]
ON 1 = 0
WHEN NOT MATCHED BY TARGET THEN
INSERT(OrderId, Amount, Cost, SaleDate)
VALUES([Source].OrderId, [Source].Amount, [Source].Cost, [Source].SaleDate)
OUTPUT Inserted.Id, [Source].OrderId, [Source].RelatedOrderId
INTO #RelatedOrder(OrderFactId, OrderId, RelatedOrderId)
;
--Insert our mappings
INSERT INTO RelatedOrderMapping(RelatedOrderId, OrderFactId, OrderId)
SELECT RelatedOrderId, OrderFactId, OrderId FROM #RelatedOrder;
GO
--Done