A SQL Server technology that supports the creation, management, and delivery of both traditional, paper-oriented reports and interactive, web-based reports.
DISCLAIMER : THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
How to calculate the running total in TSQL
In this article, we will discuss how to write a SQL Query to Calculate Running Total in SQL Server with some examples.
We will use below sample table for testing purpose.
CREATE TABLE RUNTOTAL
(
OrderID int,
OrderName varchar(100),
PurchaseNum int,
SaleNum int
)
INSERT INTO RUNTOTAL VALUES
(1,'Pen',10,20),
(1,'Pencil',13,9),
(1,'Clock',11,14),
(1,'Paper',23,17),
(2,'Calendar',30,29),
(2,'Keyboard',15,34),
(2,'Monitor',33,15),
(2,'Cup',23,16)
SELECT * FROM RUNTOTAL
With GROUP BY, summing up the PurchaseNum and SaleNum for each OrderID will get rid of some details that may be useful in future statements:
SELECT OrderID
,SUM(PurchaseNum) PurchaseNum
,SUM(SaleNum) SaleNum
FROM RUNTOTAL
GROUP BY OrderID
If we would like to show other columns like OrderNum which could not be included without making them part of the aggregation, which isn't ideal here.
If we insist on to add OrderName,,PurchaseNum and SaleNum like below, we would get one error as below.
SELECT OrderID,OrderName
,PurchaseNum,SaleNum
,SUM(PurchaseNum) PurchaseNum
,SUM(SaleNum) SaleNum
FROM RUNTOTAL
GROUP BY OrderID
However, OVER() could maintain details while still returning the summed values:
SELECT OrderID,OrderName
,PurchaseNum,SUM(PurchaseNum) OVER (PARTITION BY OrderID) TOTALPurchaseNum
,SaleNum,SUM(SaleNum) OVER (PARTITION BY OrderID) TOTALSaleNum
FROM RUNTOTAL
Each window (red border) contains the summed values for the requested partition only (By OrderID) at the base query detail level.
We could continue narrowing down the window, using ROWS or RANGE like below:
SELECT OrderID,OrderName
,PurchaseNum,SUM(PurchaseNum) OVER (PARTITION BY OrderID) PurchaseNum
,SaleNum,SUM(SaleNum) OVER (PARTITION BY OrderID ORDER BY OrderID ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) TOTALSaleNumTHISROWANDAFTER
,SUM(SaleNum) OVER (PARTITION BY OrderID) SaleNum
FROM RUNTOTAL
The totalsalenumthisrowandafter shows the total of current row and the following row using ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING.
In the same way, we could have the total of current row and the proceeding row as below using ROWS BETWEEN 1 PRECEDING AND CURRENT ROW:
SELECT OrderID,OrderName
,PurchaseNum,SUM(PurchaseNum) OVER (PARTITION BY OrderID) PurchaseNum
,SaleNum,SUM(SaleNum) OVER (PARTITION BY OrderID ORDER BY OrderID ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) TOTALSaleNumTHISROWANDBEFORE
,SUM(SaleNum) OVER (PARTITION BY OrderID) SaleNum
FROM RUNTOTAL
In addition, if we would like to have a running total of all values within a group, we could use ROWS UNBOUNDED PRECEDING to achieve.
SELECT OrderID,OrderName
,PurchaseNum,SUM(PurchaseNum) OVER (PARTITION BY OrderID) PurchaseNum
,SaleNum,SUM(SaleNum) OVER (PARTITION BY OrderID ORDER BY OrderID ROWS UNBOUNDED PRECEDING) TOTALRUNNINGSaleNum
,SUM(SaleNum) OVER (PARTITION BY OrderID) SaleNum
FROM RUNTOTAL
Finally, we could have a running total of all values without any group, we could remove the PARTITION BY OrderID part as below:
SELECT OrderID,OrderName
,PurchaseNum,SUM(PurchaseNum) OVER (PARTITION BY OrderID) PurchaseNum
,SaleNum,SUM(SaleNum) OVER (ORDER BY OrderID ROWS UNBOUNDED PRECEDING) WHOLETOTALRUNNINGSaleNum
,SUM(SaleNum) OVER (PARTITION BY OrderID) SaleNum
FROM RUNTOTAL
DISCLAIMER : THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.