Ben*_*sen 5 sql t-sql sql-server ssis
我有一个包含公司内所有项目的表格 - 项目表格.每行代表一个项目,其中包含每个属性的最新值(例如单位价格,此项目的利润,供应商,描述等).
ItemNo | Description | Unit Price | Profit % |
----------------------------------------------
1 | MyItem | 200 | 47 |
2 | MyOtherItem | 300 | 25 |
Run Code Online (Sandbox Code Playgroud)
在另一个表中,我对Item-table进行了历史更改 - ChangeLog History Table它显示了ItemNo,已更改的列,旧值和新值以及显示更改发生时间的DateCreated列.像这样:
ItemNo | ColumnName | OldValue | New Value | DateCreated |
-----------------------------------------------------------
1 | Unit Price | 50 | 100 | 20170401 |
1 | Unit Price | 100 | 200 | 20170501 |
2 | Profit % | 2 | 25 | 20170603 |
1 | Profit % | 99 | 47 | 20170604 |
Run Code Online (Sandbox Code Playgroud)
我想创建一个看起来像Item表的表,但是根据Changelog Hisotry表,使用ValidFrom和ValidTo Date按时间顺序跟踪所有更改.所以开头的Item-table应该如下所示:
ItemNo | Description | Unit Price | Profit % | ValidFrom | ValidTo
-------------------------------------------------------------------
1 | MyItem | 200 | 47 | 2017-06-04 | 9999-12-31
1 | MyItem | 200 | 99 | 2017-05-01 | 2017-06-04
1 | MyItem | 100 | 99 | 2017-04-01 | 2017-05-01
1 | MyItem | 50 | 99 | 1900-01-01 | 2017-04-01
2 | MyOtherItem | 300 | 25 | 2017-06-03 | 9999-12-31
2 | MyOtherItem | 300 | 2 | 1900-01-01 | 2017-06-03
Run Code Online (Sandbox Code Playgroud)
所以问题是如何使用T-SQL创建它?我掌握了SSIS,但是我不知道如何解决这个问题,一直试图让我的头脑绕了好几个小时.
提前致谢!
尝试一下这个,对于 2 列:
WITH hist AS (
-- sample change log data
select *
from (
Values
(1,'Unit Price',50 ,100, cast('20170401' as date))
,(1,'Unit Price',100,200,'20170501')
,(2,'Profit %', 2 , 25,'20170603')
,(1,'Profit %', 99, 47,'20170604')
) t(ItemNo,ColumnName,OldValue,NewValue,DateCreated )
),
items AS(
-- sample items data
select *
from (
Values
(1, 'MyItem',211,4)
,(2,'MyOtherItem',311,2)
) t(ItemNo,Description,UnitPrice,[Profit %])
),
-- Solution
hist2 AS (
-- Add the very old values from change log as new starting at 1900-01-01
SELECT *
FROM hist
UNION ALL
SELECT TOP(1) WITH TIES ItemNo, ColumnName, null, OldValue, '19000101'
FROM hist
ORDER BY row_number() over (partition by ItemNo, ColumnName order by DateCreated)
),
intv AS (
-- Get itervals from augmented change log
SELECT ItemNo
, sD = DateCreated
, eD = coalesce(dateadd(day, -1, lead(DateCreated) over (partition by ItemNo order by DateCreated)),'99991231')
FROM (
SELECT DISTINCT ItemNo, DateCreated
FROM hist2
) t
)
-- Fill intervals with values from augmented change log, using Items values as a last resort
SELECT items.ItemNo, items.Description, Sd, Ed
, coalesce(p1.UnitPrice, items.UnitPrice)
, coalesce(p2.[Profit %], items.[Profit %])
FROM intv
OUTER APPLY (
select top(1) UnitPrice = NewValue
from hist2 h
where h.ItemNo = intv.ItemNo and h.ColumnName = 'Unit Price' and DateCreated <= Ed
order by DateCreated desc
) p1
OUTER APPLY (
select top(1) [Profit %] = NewValue
from hist2 h
where h.ItemNo = intv.ItemNo and h.ColumnName = 'Profit %' and DateCreated <= Ed
order by DateCreated desc
) p2
JOIN items ON items.ItemNo = intv.ItemNo
Run Code Online (Sandbox Code Playgroud)
您可能想要实例化 hist2 并添加适当的索引以获得更好的性能。