2012-02-23 12 views
1

私はデータウェアハウスプロジェクトを担当しており、クライアントは毎日の販売データを提供しています。手元の数量はほとんどの行に表示されますが、しばしば欠落しています。以前のOHと販売情報に基づいて欠損値を埋める方法については、私は助けが必要です。
T-SQL - 実行残高のギャップを埋める

ここでサンプルデータです:ONHAND量が存在するため

Line# Store Item OnHand SalesUnits DateKey 
----------------------------------------------- 
1  001 A  100  20   1  
2  001 A  80  10   2  
3  001 A  null 30   3  --[OH updated with 70 (80-10)] 
4  001 A  null 5   4  --[OH updated with 40 (70-30)] 
5  001 A  150  10   5  --[OH untouched] 
6  001 B  null 4   1  --[OH untouched - new item] 
7  001 B  80  12   2  
8  001 B  null 10   3  --[OH updated with 68 (80-12] 

ライン1及び2が更新されるべきではありません。
行3と行4は、その前の行に基づいて更新されます。
OnHandが提供されているため、ライン5は変更されません。
6行目は、項目B

ための最初の行は、私はセット操作でこれを行うことができます方法はありですので、手付かずのままにすることがありますか?私はfast_forwardカーソルを使って簡単にそれを行うことができますが、長い時間(15M +行)かかるでしょう。

ありがとうございました!

+0

@Diegoからスクリプトを実行しないと、データが壊れてしまいます。 –

答えて

0

テストデータ:

declare @t table(
Line# int, Store char(3), Item char, OnHand int, SalesUnits int, DateKey int 
) 

insert @t values 
(1, '001', 'A', 100, 20, 1), 
(2, '001', 'A', 80 , 10, 2), 
(3, '001', 'A', null, 30, 3), 
(4, '001', 'A', null, 5, 4), 
(5, '001', 'A', 150, 10, 5), 
(6, '001', 'B', null, 4, 1), 
(7, '001', 'B', null, 4, 2), 
(8, '001', 'B', 80, 12, 3), 
(9, '001', 'B', null, 10, 4) 

スクリプトカーソルを使用していない移入する:私は、私はあなたがカーソルのバージョンを使用recommand

declare @datekey int, @store int, @item char, @Onhand int, 
@calculatedonhand int, @salesunits int, @laststore int, @lastitem char 

DECLARE sales_cursor 
CURSOR FOR 
SELECT datekey+1, store, item, OnHand -SalesUnits, salesunits 
FROM @t sales 
order by store, item, datekey 

OPEN sales_cursor; 
FETCH NEXT FROM sales_cursor 
INTO @datekey, @store, @item, @Onhand, @salesunits 

WHILE @@FETCH_STATUS = 0 
BEGIN 
SELECT @calculatedonhand = case when @laststore = @store and @lastitem = @item 
then coalesce(@onhand, @calculatedonhand - @salesunits) else null end 
,@laststore = @store, @lastitem = @item 

UPDATE s 
SET [email protected] 
FROM @t s 
WHERE datekey = @datekey and @store = store and @item = item 
and onhand is null and @calculatedonhand is not null 

FETCH NEXT FROM sales_cursor 
INTO @datekey, @store, @item, @Onhand, @salesunits 

END 
CLOSE sales_cursor; 
DEALLOCATE sales_cursor; 

:カーソルを使用して移入する

;with a as 
(
select Line#, Store, Item, OnHand, SalesUnits, DateKey, 1 correctdata from @t where DateKey = 1 
union all 
select t.Line#, t.Store, t.Item, coalesce(t.OnHand, a.onhand - a.salesunits), t.SalesUnits, t.DateKey, t.OnHand from @t t 
join a on a.DateKey = t.datekey - 1 and a.item = t.item and a.store = t.store 
) 
update t 
set OnHand = a.onhand 
from @t t join a on a.line# = t.line# 
where a.correctdata is null 

スクリプトをあなたは再帰的なクエリを使用してまともなパフォーマンスを得ることができます疑い。私はここのカーソルを嫌う人を知っていますが、あなたのテーブルにそのサイズがあるときは、それが唯一の解決策になります。

+0

ありがとうございます - 私はこの場合、私のgood'olカーソルに固執します。 :) –

+0

@ GustavoCavalcantiは自分自身のカーソルの大ファンではないが、時には彼らはネササリの悪である。私はそれがあなたのパフォーマンスを改善したと思うヌル行のみを更新することに注意してください –

関連する問題