Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 213241
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T18:15:36+00:00 2026-05-11T18:15:36+00:00

Imagine the following table (called TestTable ): id somedate somevalue — ——– ——— 45

  • 0

Imagine the following table (called TestTable):

id     somedate    somevalue
--     --------    ---------
45     01/Jan/09   3
23     08/Jan/09   5
12     02/Feb/09   0
77     14/Feb/09   7
39     20/Feb/09   34
33     02/Mar/09   6

I would like a query that returns a running total in date order, like:

id     somedate    somevalue  runningtotal
--     --------    ---------  ------------
45     01/Jan/09   3          3
23     08/Jan/09   5          8
12     02/Feb/09   0          8
77     14/Feb/09   7          15  
39     20/Feb/09   34         49
33     02/Mar/09   6          55

I know there are various ways of doing this in SQL Server 2000 / 2005 / 2008.

I am particularly interested in this sort of method that uses the aggregating-set-statement trick:

INSERT INTO @AnotherTbl(id, somedate, somevalue, runningtotal) 
   SELECT id, somedate, somevalue, null
   FROM TestTable
   ORDER BY somedate

DECLARE @RunningTotal int
SET @RunningTotal = 0

UPDATE @AnotherTbl
SET @RunningTotal = runningtotal = @RunningTotal + somevalue
FROM @AnotherTbl

… this is very efficient but I have heard there are issues around this because you can’t necessarily guarantee that the UPDATE statement will process the rows in the correct order. Maybe we can get some definitive answers about that issue.

But maybe there are other ways that people can suggest?

edit: Now with a SqlFiddle with the setup and the ‘update trick’ example above

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T18:15:36+00:00Added an answer on May 11, 2026 at 6:15 pm

    Update, if you are running SQL Server 2012 see: https://stackoverflow.com/a/10309947

    The problem is that the SQL Server implementation of the Over clause is somewhat limited.

    Oracle (and ANSI-SQL) allow you to do things like:

     SELECT somedate, somevalue,
      SUM(somevalue) OVER(ORDER BY somedate 
         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
              AS RunningTotal
      FROM Table
    

    SQL Server gives you no clean solution to this problem. My gut is telling me that this is one of those rare cases where a cursor is the fastest, though I will have to do some benchmarking on big results.

    The update trick is handy but I feel its fairly fragile. It seems that if you are updating a full table then it will proceed in the order of the primary key. So if you set your date as a primary key ascending you will probably be safe. But you are relying on an undocumented SQL Server implementation detail (also if the query ends up being performed by two procs I wonder what will happen, see: MAXDOP):

    Full working sample:

    drop table #t 
    create table #t ( ord int primary key, total int, running_total int)
    
    insert #t(ord,total)  values (2,20)
    -- notice the malicious re-ordering 
    insert #t(ord,total) values (1,10)
    insert #t(ord,total)  values (3,10)
    insert #t(ord,total)  values (4,1)
    
    declare @total int 
    set @total = 0
    update #t set running_total = @total, @total = @total + total 
    
    select * from #t
    order by ord 
    
    ord         total       running_total
    ----------- ----------- -------------
    1           10          10
    2           20          30
    3           10          40
    4           1           41
    

    You asked for a benchmark this is the lowdown.

    The fastest SAFE way of doing this would be the Cursor, it is an order of magnitude faster than the correlated sub-query of cross-join.

    The absolute fastest way is the UPDATE trick. My only concern with it is that I am not certain that under all circumstances the update will proceed in a linear way. There is nothing in the query that explicitly says so.

    Bottom line, for production code I would go with the cursor.

    Test data:

    create table #t ( ord int primary key, total int, running_total int)
    
    set nocount on 
    declare @i int
    set @i = 0 
    begin tran
    while @i < 10000
    begin
       insert #t (ord, total) values (@i,  rand() * 100) 
        set @i = @i +1
    end
    commit
    

    Test 1:

    SELECT ord,total, 
        (SELECT SUM(total) 
            FROM #t b 
            WHERE b.ord <= a.ord) AS b 
    FROM #t a
    
    -- CPU 11731, Reads 154934, Duration 11135 
    

    Test 2:

    SELECT a.ord, a.total, SUM(b.total) AS RunningTotal 
    FROM #t a CROSS JOIN #t b 
    WHERE (b.ord <= a.ord) 
    GROUP BY a.ord,a.total 
    ORDER BY a.ord
    
    -- CPU 16053, Reads 154935, Duration 4647
    

    Test 3:

    DECLARE @TotalTable table(ord int primary key, total int, running_total int)
    
    DECLARE forward_cursor CURSOR FAST_FORWARD 
    FOR 
    SELECT ord, total
    FROM #t 
    ORDER BY ord
    
    
    OPEN forward_cursor 
    
    DECLARE @running_total int, 
        @ord int, 
        @total int
    SET @running_total = 0
    
    FETCH NEXT FROM forward_cursor INTO @ord, @total 
    WHILE (@@FETCH_STATUS = 0)
    BEGIN
         SET @running_total = @running_total + @total
         INSERT @TotalTable VALUES(@ord, @total, @running_total)
         FETCH NEXT FROM forward_cursor INTO @ord, @total 
    END
    
    CLOSE forward_cursor
    DEALLOCATE forward_cursor
    
    SELECT * FROM @TotalTable
    
    -- CPU 359, Reads 30392, Duration 496
    

    Test 4:

    declare @total int 
    set @total = 0
    update #t set running_total = @total, @total = @total + total 
    
    select * from #t
    
    -- CPU 0, Reads 58, Duration 139
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 119k
  • Answers 119k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer The preferences for each individual widget and the dashboard itself… May 11, 2026 at 11:50 pm
  • Editorial Team
    Editorial Team added an answer you can just copy and paste the innerhtml. var data… May 11, 2026 at 11:50 pm
  • Editorial Team
    Editorial Team added an answer What you're after a data binding framework for XML. The… May 11, 2026 at 11:50 pm

Related Questions

Imagine the following table (called TestTable ): id somedate somevalue -- -------- --------- 45
Imagine the following problem: You have a database containing about 20,000 texts in a
I've got a table, called faq_questions with the following structure: id int not_null auto_increment,
Imagine I have a service that looks like this: public interface MyAccountService { boolean
Imagine the following tables: create table boxes( id int, name text, ...); create table

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.