2011-12-14 2 views
0

나는 각 내가 가진 행복 (재귀 CTE를 통해) 합계 지출에 추가 지출 볼 수있는 바와 같이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 

아래에 결과가-설정했습니다. 로직 타입의 밸런스를 그 = 최고 최대 그래서

  • 아무것도,

    나는 것을 = 투자 초기에

    • 급파 값까지 이렇게 일을 할애해야하지만

      보기 :

      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

    나는, 어떻게에 가기의 손실에 조금이다. Google의보기 "분할 행"검색 페이지를 읽으십시오. 그러나 그들은 모두 내가 필요로하는 것에 대해 강렬 해 보입니다. 자기 조인에 대해 생각하고 있지만 어디서부터 시작해야할지 모르겠습니다. –

    답변

    1

    분할 행을 수행하려면 CTE에 두 개의 UNION 절을 추가해야합니다. 대부분의 재귀 적 CTE에는 "앵커"와 재귀 적 비트가 있습니다. 재귀 비트가 어떻게 작동하는지 확장해야합니다. 첫째, "명목상"의 경우를 압박해야 할 때를 확인합니다. 이는 균형이 양수에서 음수로 바뀔 때입니다. 귀하의 경우에는 "DespatchValue + SumSpend"입니다.

    다음 두 용어는 "분할 된"행입니다. 위에있는 조건의 역수를 사용합니다 (즉,이 "특수"조건에 대해서만 행을 가져옵니다). 첫 번째 UNION은 "BALANCE"레코드가됩니다. 두 번째는 남은 것의 나머지입니다.

    여기에 제가 생각해 냈습니다. "균형"을 나타 내기 위해 (그리고 이후의 재귀에서 중복을 방지하기 위해) "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)