在更新表时将值分配给所有行

Sha*_*ggy 9 sql sql-server sql-server-2008

我有表格结构 tblCustData

ID    UserID    Fee FeePaid
 1      12      150   0
 2      12      100   0
 3      12      50    0
Run Code Online (Sandbox Code Playgroud)

并且值要在FeePaidColumn 中更新,如果我在@Amt变量中有值200那么它应该更新任何两行

输出应该是这样的

ID    UserID    Fee FeePaid
1      12       150   150
2      12       100   50
3      12       50    0
Run Code Online (Sandbox Code Playgroud)

FeePaid不应该研磨器比Fee列,但如果我通过350@Amt可变它应产生像输出

ID    UserID    Fee FeePaid
1       12      150   200
2       12      100   100
3       12      50    50
Run Code Online (Sandbox Code Playgroud)

仅当@Amt超过Fee列中的总值时

我想不出这个问题

Update tblCustData
Set FeePaid=@Amt
Where UserID=12
Run Code Online (Sandbox Code Playgroud)

val*_*lex 5

首先使用CTE语法,我们准备一个带有sums分布的表,然后使用唯一字段Code更新主表,使用CASE来处理所有可能的方式(包括带有余数的第一行).

Declare @Amt int;
SET @Amt=250;


with T as 
(
   SELECT ROW_NUMBER() OVER (ORDER BY Fee desc) as rn, *
   FROM tblCustData WHERE UserId=12
)  
,T2 as 
(
   SELECT *,
          ISNULL((SELECT SUM(Fee-FeePaid) FROM T WHERE T1.RN<RN),0) as PrevSum 
   FROM T as T1
 )

UPDATE
    A
SET A.FeePaid = A.FeePaid+ CASE WHEN (B.PrevSum+B.Fee-B.FeePaid<=@Amt) 
                                     AND (B.RN<>1) 
                                        THEN B.Fee-B.FeePaid
                     WHEN (B.PrevSum+B.Fee-B.FeePaid<=@Amt) AND (B.RN=1) 
                                        THEN @Amt-B.PrevSum
                     WHEN B.PrevSum>=@Amt 
                                        THEN 0                 
                     WHEN B.PrevSum+B.Fee-B.FeePaid>@Amt 
                                        THEN @Amt-B.PrevSum
              END
FROM
    tblCustData A
    JOIN T2 B ON A.Code = B.Code
GO
Run Code Online (Sandbox Code Playgroud)

SQLFiddle demo