2011-12-14 51 views
0

我有一個結果集以下T-SQL拆分行?

Rank cardID  DespatchValue Spend SumSpend Spendtype 
0  468612  500    0   0   Despatch 
1  468612  500    -8500  -8500  Topup 
2  468612  500   -11500  -20000  Topup 
3  468612  500    -3500  -23500  Topup 

正如你可以看到每個花加到總支出(通過遞歸CTE),我很高興的。

但是邏輯需要這樣的工作

  • 迪斯派奇價值高達初始花費=花型平衡
  • 凡是=頂起來

所以後,

我會喜歡看:

Rank cardID DespatchValue Spend SumSpend Spendtype 
0  468612 500    0  0  Despatch 
?  468612 500    -500 -500  Balance 
1  468612 500    -8000 -8500  Topup 
2  468612 500    -11500 -20000  Topup 
3  468612 500    -3500 -23500  Topup 

有關如何實現此目的的任何想法?

+0

不多,我有點茫然如何去。在谷歌閱讀一個視圖「拆分行」搜索頁面,但他們都看起來有點激烈,我需要什麼。思考一個自我加入,但不知道從哪裏開始 – 2011-12-14 10:02:30

回答

1

要做一個拆分行,你需要爲你的CTE增加兩個UNION子句。大多數遞歸CTE都有一個「錨點」和一個遞歸位。您需要擴展該遞歸位的工作方式。首先,您需要確定何時抑制「名義」情況,這對您而言是當餘額從正值總量轉換爲負值時。在你的情況下,這是「DespatchValue + SumSpend」。

接下來的兩個術語將是你的「拆分」行。使用上面任何條件的逆(即,只在這個「特殊」條件下才能使行恢復)。第一個聯盟將成爲「平衡」記錄,將其降至0.第二個是餘下的剩餘部分。

下面是我想到的 - 注意,我添加了一個「subid」列來指示「平衡」(並防止在以後的遞歸中出現重複)。我還添加了一個「DespatchBalance」,假設你真的在檢查什麼。除了具體情況,一般格式應該是好的:

declare @txn as table (
    id int, 
    cardID int, 
    DespatchValue int, 
    Spend int 
    --SumSpend int, 
    --Spendtype varchar(50) 
) 

insert into @txn 
        select 0, 468612, 500, 0--, 0, 'Despatch' 
union all select 1, 468612, 500, -8500--, -8500, 'Despatch' 
union all select 2, 468612, 500, -11500--, -20000, 'Despatch' 
union all select 3, 468612, 500, -3500--, -23500, 'Despatch' 


;with x (id, subid, cardID, DespatchValue, Spend, SumSpend, DespatchBalance, Despatch) as 
(
    --Anchor - beginning record 
    select id, 0, cardID, DespatchValue, Spend 
    , Spend as SumSpend 
    , DespatchValue as DespatchBalance 
    , 'Despatch' as Despatch 
    from @txn 
    where id = 0 

    UNION ALL  
    -- primary CTE - identify all nominal 'Topup' records 
    select t.id, 0, t.cardID, t.DespatchValue, t.Spend 
    , x.SumSpend + t.Spend 
    , x.DespatchBalance + t.Spend 
    , 'Topup' 
    from @txn t 
    join x 
     on x.id + 1 = t.id 
     and x.subid = 0 
    where x.DespatchBalance <= 0 

    UNION ALL 

    -- These two UNIONs do a split record: 

    -- First half of split - the remaining amount to a balance of 0 
    select t.id, 1 -- special "subid" to indicate it's a split record 
    , t.cardID, t.DespatchValue 
    , - x.DespatchBalance 
    , x.SumSpend - x.DespatchValue -- only capture the remaing bit above balance 
    , 0 -- DespatchBalance should be 0 
    , 'Balanace' 
    from @txn t 
    join x 
     on x.id + 1 = t.id 
     and x.subid = 0 
    where x.DespatchBalance > 0 
     and x.DespatchBalance + t.Spend < 0 

    UNION ALL 
    -- Second half of split - record that this is an overflow after "Balance" reached 
    select t.id, 0 
    , t.cardID, t.DespatchValue 
    , t.Spend + x.DespatchBalance 
    , x.SumSpend + t.Spend 
    , x.DespatchBalance + t.Spend 
    , 'Topup' 
    from @txn t 
    join x 
     on x.id + 1 = t.id 
     and x.subid = 0 
    where x.DespatchBalance > 0 
     and x.DespatchBalance + t.Spend < 0 
) 

select * 
from x 
option (MAXRECURSION 100)