如何在不使用游标的情况下计算SQL中的运行总计?

Chr*_*all 24 sql sql-server

为简洁起见,我省略了所有光标设置和临时表中的SELECT.基本上,此代码计算每个事务的所有事务的运行余额.

WHILE @@fetch_status = 0
BEGIN

    set @balance = @balance+@amount

    insert into @tblArTran values ( --from artran table
                @artranid, @trandate, @type, 
                @checkNumber, @refNumber,@custid,
                @amount, @taxAmount, @balance, @postedflag, @modifieddate )


    FETCH NEXT FROM artranCursor into 
            @artranid, @trandate, @type, @checkNumber, @refNumber,
            @amount, @taxAmount,@postedFlag,@custid, @modifieddate

END
Run Code Online (Sandbox Code Playgroud)

从另一个问题的答案中受到此代码的启发,

SELECT @nvcConcatenated = @nvcConcatenated + C.CompanyName + ', '
FROM tblCompany C
WHERE C.CompanyID IN (1,2,3)
Run Code Online (Sandbox Code Playgroud)

我想知道如果你得到了我的意思,SQL是否能够以与连接字符串相同的方式对数字求和.也就是说,在不使用游标的情况下每行创建一个"运行平衡".

可能吗?

jan*_*son 20

您可能需要查看本地变量解决方案的更新:http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005---该-optimal.aspx

DECLARE @SalesTbl TABLE (DayCount smallint, Sales money, RunningTotal money)

DECLARE @RunningTotal money

SET @RunningTotal = 0

INSERT INTO @SalesTbl 
SELECT DayCount, Sales, null
FROM Sales
ORDER BY DayCount

UPDATE @SalesTbl
SET @RunningTotal = RunningTotal = @RunningTotal + Sales
FROM @SalesTbl

SELECT * FROM @SalesTbl
Run Code Online (Sandbox Code Playgroud)

优于所有其他方法,但对保证行顺序有一些疑问.当临时表被索引时似乎工作正常..

  • 嵌套子查询9300毫秒
  • 自我加入6100毫秒
  • 光标400毫秒
  • 更新到局部变量140毫秒

  • Aaron Bertrand对此方法(http://stackoverflow.com/a/11313533/26167)的各种方法进行了很好的概述,包括围绕这种方法的更多注意事项. (2认同)

Aar*_*ton 10

SQL 可以在不使用游标的情况下创建运行总计,但它是少数几种情况之一,其中游标实际上比基于集合的解决方案更高性能(给定SQL Server中当前可用的运算符).或者,CLR功能有时可以很好地发挥作用.Itzik Ben-Gan在SQL Server Magazine上发表了关于运行聚合的优秀系列.该系列节目在上个月结束,但如果您有在线订阅,您可以访问所有文章.

编辑:这是他在该系列中的最新文章(SQL CLR).鉴于您可以通过购买一个月的在线月票 - 少于6美元来访问整个系列 - 如果您有兴趣从各个角度查看问题,那么值得您花些时间.Itzik是一个Microsoft MVP和一个非常聪明的TSQL编码器.


Qua*_*noi 8

OraclePostgreSQL 8.4你可以使用窗口功能:

SELECT  SUM(value) OVER (ORDER BY id)
FROM    mytable
Run Code Online (Sandbox Code Playgroud)

MySQL,您可以使用会话变量用于相同的目的:

SELECT  @sum := @sum + value
FROM    (
        SELECT  @sum := 0
        ) vars, mytable
ORDER BY
        id
Run Code Online (Sandbox Code Playgroud)

SQL Server,它是一个罕见的光标是首选解决方案的任务示例.

  • 如果您可以访问SQL Server 2012,则可以使用相同的窗口函数来计算运行总计. (5认同)