SQL 2016 Hosting Italy – SQL Server: How to Calculate running totals using T-SQL?
|This is not a new topic. If you search, you may sure realize several posts on this, largely with old techniques however not using newest capabilities like SQL 2016 Windowing. Since I wrote a post on Analysis Services for identical, thought to put in writing the same on T-SQL too. Here is that the approach of calculating running totals using Window components and functions that provides an efficient way of calculating and easy code structure.
The following question shows the approach of calculating. the primary code creates a window based on SalesOrderId (which is unique) and obtain the running totals over SubTotal for a given year. The second code creates a window on OrderDate (which isn’t unique). this may show the totals for the date rather than Running-Totals for the date unless the range is nominative using boundaries. that’s the explanation for adding upper and lower boundaries using ROW, UNBOUNED PRECEDING and CURRENT ROW within the window for restricting rows to be participated for the calculation.
1 2 3 4 5 6 7 8 9 10 11 12 |
SELECT OrderDate, SalesOrderID, SalesOrderNumber, CustomerID , SubTotal Total , SUM(SubTotal) OVER(ORDER BY SalesOrderID) RunningTotal FROM Sales.SalesOrderHeader ORDER BY OrderDate, SalesOrderID -- Window based on OrderDate which is not unique SELECT OrderDate, SalesOrderID, SalesOrderNumber, CustomerID , SubTotal Total , SUM(SubTotal) OVER(ORDER BY OrderDate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) RunningTotal FROM Sales.SalesOrderHeader ORDER BY OrderDate, SalesOrderID |
Here may be a comparison on a similar using old techniques. tho’ it shows that the query uses window is quicker than different queries, always check and choose the most effective.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
SELECT OrderDate, SalesOrderID, SalesOrderNumber, CustomerID , SubTotal Total , SUM(SubTotal) OVER(ORDER BY SalesOrderID) RunningTotal FROM Sales.SalesOrderHeader WHERE YEAR(OrderDate) = 2016 ORDER BY OrderDate, SalesOrderID -- Using self-join SELECT h1.OrderDate, h1.SalesOrderID, h1.SalesOrderNumber, h1.CustomerID , h1.SubTotal Total , SUM(h2.SubTotal) RunningTotal FROM Sales.SalesOrderHeader h1 INNER JOIN Sales.SalesOrderHeader h2 ON h1.SalesOrderID >= h2.SalesOrderID AND YEAR(h2.OrderDate) = 2016 WHERE YEAR(h1.OrderDate) = 2016 GROUP BY h1.OrderDate, h1.SalesOrderID, h1.SalesOrderNumber , h1.CustomerID, h1.SubTotal ORDER BY h1.OrderDate, h1.SalesOrderID -- Using sub query SELECT h1.OrderDate, h1.SalesOrderID, h1.SalesOrderNumber, h1.CustomerID , h1.SubTotal Total , (SELECT SUM(h2.SubTotal) RunningTotal FROM Sales.SalesOrderHeader h2 WHERE h1.SalesOrderID >= h2.SalesOrderID AND YEAR(h2.OrderDate) = 2006) FROM Sales.SalesOrderHeader h1 WHERE YEAR(h1.OrderDate) = 2016 ORDER BY h1.OrderDate, h1.SalesOrderID |