• subscribe
May 19, 2009 12:00 AM

Set-Based vs. Cursor-Based Solutions for Running Aggregates

Use cursors for large partitions
SQL Server Pro
InstantDoc ID #101736


Listing 6: Cursor-Based Solution with Multiple Aggregations
DECLARE @Result AS TABLE
(
empid INT,
dt DATETIME,
qty INT,
val MONEY,
sumqty BIGINT,
avgqty NUMERIC(12, 2),
sumval MONEY,
avgval MONEY
);

DECLARE
@empid AS INT,
@prvempid AS INT,
@dt AS DATETIME,
@qty AS INT,
@val AS MONEY,
@sumqty AS BIGINT,
@sumval AS MONEY,
@count AS INT;

DECLARE C CURSOR FAST_FORWARD FOR
SELECT empid, dt, qty, val
FROM dbo.Sales
ORDER BY empid, dt;

OPEN C

FETCH NEXT FROM C INTO @empid, @dt, @qty, @val;

SELECT @prvempid = @empid, @sumqty = 0, @sumval = 0, @count = 0;

WHILE @@fetch_status = 0
BEGIN
IF @empid @prvempid
SELECT @prvempid = @empid, @sumqty = 0, @sumval = 0, @count = 0;

SELECT
@sumqty = @sumqty + @qty,
@sumval = @sumval + @val,
@count = @count + 1;

INSERT INTO @Result(empid, dt, qty, val, sumqty, avgqty, sumval, avgval)
VALUES(@empid, @dt, @qty, @val,
@sumqty, 1.*@sumqty / @count, @sumval, @sumval / @count);

FETCH NEXT FROM C INTO @empid, @dt, @qty, @val;
END

CLOSE C;

DEALLOCATE C;

SELECT * FROM @Result;



ARTICLE TOOLS

Comments
  • dianagele
    1 year ago
    May 21, 2011

    loved it.
    note: Listing 2 has a syntax in the WHERE statement?
    this line --> "SELECT n FROM Nums WHERE n"

  • WAYNE
    3 years ago
    Jun 04, 2009

    This set based method is using an inefficient triangular-join. There are other set-based methods that will blow this (and, obviously, the cursor) away.
    See http://www.sqlservercentral.com/Forums/FindPost728664.aspx for a set-based example of a one million row running update that runs in 35 seconds, and a corresponding cursor-based solution that runs in 144 seconds.

    [Reply:
    Hi wgshef,

    Thanks for your comment. The technique that you refer to as a more efficient set-based solution is one that I wouldn’t recommend using. I don’t have enough room to elaborate here; please see my response in the following blog entry: http://www.sqlmag.com/Article/ArticleID/102251/sql_server_102251.html.

    Cheers,
    BG]

You must log on before posting a comment.

Are you a new visitor? Register Here