SQL Server 查询:调整货币列

Posted

技术标签:

【中文标题】SQL Server 查询:调整货币列【英文标题】:SQL Server query: Adjust money column 【发布时间】:2015-10-30 13:37:39 【问题描述】:

我正在尝试在没有光标的情况下执行以下操作。有可能吗?

我有这个变量:

DECLARE @Amount MONEY = 800;

我目前拥有的示例表:

EntryID    Amount
--------------------------------------------
1       200
2       250
3       600
4       100
...     ....(could be many more rows)

我希望能够更新表格以仅显示需要添加到 @Amount 变量 ($800) 的“金额”。所以我希望表格最终是这样的:

EntryID    Amount
--------------------------------------------
1       200 (uses up full 200)
2       250 (uses up full 250)
3       350 (uses up 350 of the 600)

或者喜欢这个

EntryID    Amount     Distrib
--------------------------------------------
1       200        200
2       250        250
3       600        350
4       100        0
...     ...            ...

所以SUM() 等于@Amount

提前致谢!

PS - 我在 SQL Server 2012 中这样做

更新:

这是我的最终解决方案。再次感谢戈登:

DECLARE @Amount money = 800;
DECLARE @tmpPaymentDist TABLE (EntryID INT, Amount MONEY, Distrib MONEY);

INSERT INTO @tmpPaymentDist (EntryID, Amount) VALUES (1, 200);
INSERT INTO @tmpPaymentDist (EntryID, Amount) VALUES (2, 250);
INSERT INTO @tmpPaymentDist (EntryID, Amount) VALUES (3, 600);
INSERT INTO @tmpPaymentDist (EntryID, Amount) VALUES (4, 100);

with toupdate as (
    select t.*,
        (case when sum(amount) over (order by entryid) <= @amount
        then amount
        when sum(amount) over (order by entryid) < @amount + amount
        then @amount - (sum(amount) over (order by entryid) - amount)
        else 0
    end) as new_distrib
    from @tmpPaymentDist t
)

update T set distrib = new_distrib 
FROM @tmpPaymentDist T
INNER JOIN toupdate T2 ON T2.EntryID = T.EntryID
WHERE T2.new_distrib > 0

SELECT * FROM @tmpPaymentDist

【问题讨论】:

【参考方案1】:

是的,您可以在没有光标的情况下使用累积和来执行此操作:

select t.*,
       (case when sum(amount) over (order by entryid) <= @amount
             then amount
             when sum(amount) over (order by entryid) < @amount + amount
             then @amount - (sum(amount) over (order by entryid) - amount)
             else 0
        end) as distrib
from table t;

也就是说,使用累积和进行计算。

对于update,您可以使用相同的逻辑:

with toupdate as (
      select t.*,
             (case when sum(amount) over (order by entryid) <= @amount
                   then amount
                   when sum(amount) over (order by entryid) < @amount + amount
                   then @amount - (sum(amount) over (order by entryid) - amount)
                   else 0
              end) as new_distrib
      from table t
     )
update toudpate
    set distrib = new_distrib;

【讨论】:

它工作!我知道这将是一件疯狂的事情!大声笑感谢戈登的帮助

以上是关于SQL Server 查询:调整货币列的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server:通过查询找出列的默认值

使用函数调整 SQL Server 查询

在 SQL Server 中调整大型查询

SQL Server:从查询返回的动态列

带有相关子查询的 While 循环的 SQL Server 性能调整

sql server 2005多表连接查询,去除部分列不查询