2009-10-14 15 views
0

我有兩個表 - 我們姑且稱之爲dbo.ValuesToReduce和dbo.Reserve 在第一表中的數據(dbo.ValuesToReduce)是:減少一個表中的值,直到儲備在另一個表中消耗 - 遞歸?

ValuesToReduceId | PartnerId | Value 
------------------------------------- 
1    | 1   | 53.15 
2    | 2   | 601.98 
3    | 1   | 91.05 
4    | 2   | 44.56 
5    | 3   | 19.11 

第二個表(dbo.Reserve)看起來像這樣

ReserveId | PartnerId | Value 
------------------------------- 
1   | 1   | -101.55 
2   | 2   | -425.19 
3   | 3   | -28.17 

我需要做的是:使用後面的Reserves表更新ValuesToReduce表中的值,減少數量直到備用電源耗盡。這就是我要運行腳本後得到:

ValuesToReduceId | PartnerId | Value 
------------------------------------- 
1    | 1   | 0.00 
2    | 2   | 176.79 
3    | 1   | 42.65 
4    | 2   | 44.56 
5    | 3   | 0.00 


ReserveId | PartnerId | Value 
------------------------------- 
1   | 1   | 0.00 
2   | 2   | 0.00 
3   | 3   | -9.06 

因此,基本上,每個合作伙伴都有「儲備」,他會耗盡,並在值表中的值應該由相應的合作伙伴可以減少,如果仍然有東西在儲備。儲備應按照ValuesToReduceId提供的順序配置。

對於1 PARTNERID的合作伙伴,你可以看到,他有足夠的儲備來更新他的第一個值爲0,仍然有一些留下來減少由量的第二值。

ID爲2的合作伙伴有425.19的儲備金,該合作伙伴的價值表中有兩個條目601.98和44.56(按ValuesToReduceId),所以我們只更新了儲備金以來的第一個值對於兩者來說都不夠大。錯誤的方法是將第二個值更新爲0.00,第一個值更新爲221.35。

合作伙伴與3號有足夠的儲備比較多,所以他的值更新爲0後,他留下了-9.06

我試着用遞歸CTE的東西,但我似乎無法左右我的頭它。 希望我所描述的問題不夠清楚..

+0

爲什麼你必須使用一個CTE?看來,VB和SQL的組合會產生更簡單的解決方案。 VB可以執行循環,if then else邏輯和SQL可以選擇和更新記錄? – heferav 2009-10-14 09:16:37

+0

它必須是純SQL – 2009-10-14 10:46:21

回答

1

你不能,因爲據我所知,更新一個SELECT語句兩個表。

但是你可以使用while循環爲此在SQL。搜索第一筆交易,然後執行交易,直到沒有可能的交易。

declare @valid int 
declare @resid int 
declare @val float 
while 1 = 1 
    begin 

    select top 1 
     @resid = r.ReserveId 
    , @valid = v.ValuesToReduceId 
    , @val = CASE WHEN -r.Value > v.Value THEN v.Value ELSE -r.Value END 
    from ValuesToReduce v 
    inner join Reserves r on r.PartnerId = v.PartnerId 
    where r.Value < 0 and v.Value > 0 
    order by r.ReserveId 

    if @@rowcount = 0 
     break 

    update ValuesToReduce 
    set Value = Value - @val 
    where ValuesToReduceId = @valid 

    update Reserves 
    set Value = Value + @val 
    where ReserveId = @resid 
    end 

這裏的代碼來創建測試表:

create table ValuesToReduce (
    ValuesToReduceId int, 
    PartnerId int, 
    Value float 
) 

insert into ValuesToReduce values (1,1,53.15) 
insert into ValuesToReduce values (2,2,601.98) 
insert into ValuesToReduce values (3,1,91.05) 
insert into ValuesToReduce values (4,2,44.56) 
insert into ValuesToReduce values (5,3,19.11) 

create table Reserves (
    ReserveId int, 
    PartnerId int, 
    Value float 
) 

insert into Reserves values (1,1,-101.55) 
insert into Reserves values (2,2,-425.19) 
insert into Reserves values (3,3,-28.17) 
+0

好吧,我最終使用了與此非常相似的東西,明天我會嘗試使用快速前向遊標進行優化,因爲我並不需要更改其中的值如果我可以在ValuesToReduce表中獲得正確的結果(保留儲量中的值減少值,並記錄剩餘的儲存量),則在第一次運行時保留表。我還在更新中使用調用標量函數的解決方案,但我認爲我會轉述。我會在遞歸的時候多提一點,讓我們知道如果我想出一些體面的東西。謝謝! – 2009-10-14 15:24:29

相關問題