如何根据条件添加和减去先前行的值

时间:2015-08-18 07:23:02

标签: sql sql-server-2008-r2

我有一个值为

的表格
Slno Type     Amount        
 1    P         40           
 2    C         20           
 3    P         45           
 4    P         20           
 5    C         10   

我想获得RESULT列的值。

   Type      Amount       RESULT 
    P         40           40
    C         20           20
    P         45           65
    P         20           85
    C         10           75

如果Type为C,则从前一个值中减去值, 否则,如果Type为P,则将值添加到先前的值。

这就是我尝试过的:

;WITH FINALMIDRESULT 
     AS (SELECT Type, 
                Value1, 
                Row_number() 
                  OVER( 
                    ORDER BY Slno ASC) rownum 
         FROM   #midRes) 
SELECT C1.Type, 
       C1.Value1, 
       CASE 
         WHEN C1.Type = 'C' THEN (SELECT Sum(Amount) 
                                  FROM   FINALMIDRESULT c2 
                                  WHERE  c2.rownum <= C1.rownum) 
         ELSE (SELECT Sum(Amount) - Sum(Amount) 
               FROM   FINALMIDRESULT c2 
               WHERE  c2.rownum <= C1.rownum) 
       END AS RESULT 
FROM   FINALMIDRESULT C1 

这是我得到的结果

  Type      Amount       RESULT 
    P         40           0
    C         20           60
    P         45           0
    P         20           0
    C         10           135

2 个答案:

答案 0 :(得分:0)

你需要实现一个seft INNER JOIN来汇总Slno小于当前值的所有值,如下所示:

;WITH   OriginalData    AS
(       SELECT  *
        FROM
        (       VALUES
                (1, 'P', 40),
                (2, 'C', 20),
                (3, 'P', 45),
                (4, 'P', 20),
                (5, 'C', 10)
        )       AS Temp(Slno, Type, Amount)
)
SELECT      [Current].Type, [Current].Amount,
            ISNULL(SUM(
            CASE    WHEN  [Previous].Type = 'P'
                    THEN +[Previous].Amount
                    ELSE -[Previous].Amount
            END),0) + 
            CASE    WHEN  [Current].Type = 'P'
                    THEN +[Current].Amount
                    ELSE -[Current].Amount
            END Result
 FROM       OriginalData [Current]
 LEFT JOIN  OriginalData [Previous]
        ON  [Previous].Slno < [Current].Slno
GROUP BY    [Current].Slno, [Current].Type, [Current].Amount
ORDER BY    [Current].Slno

我认为你可以做出的最大改变就是转变你的心态。当您考虑“以前的值”时,您选择了一个可以解决我的任何主要编程语言的过程路径,但在SQL中快速演变为游标方法 - 在这种情况下不适合。

当谈到SQL时,你需要考虑“集合”,这样你就可以开始努力识别这些数据集并将它们组合起来。

答案 1 :(得分:0)

SELECT SlNo, Type, Amount, 
    Sum((Case when  Type='C' then -1 else 1 END)*Amount) Over(Order by SlNo)  Result
FROM TableName