Calculate the Running Total(Everything Objective: List the running total of the annual salaries. SELECT EmployeeName,AnnualSalary,SUM(AnnualSalary OVER(ORDER BY EmployeeName AS Running_Total Employee --Checking SELECT SUM(AnnualSalary AS total Employee EmployeeName AnnualSalary Running_Total Bruce 101000 101000 Chris 30000 131000 Eric 65000 196000 Jennifer 95000 291000 Joe 90000 381000 John 35000 416000 Mark 70000 486000 Mary 60000 546000 Mike 82000 628000 Paul 30000 658000 Steve 65000 723000
Calculate the Running Total (Like Items Only Note: The objective in this case is only to add the same items as a running total in another column. I have a table like this. Date Item BuyItem ---------------------------------------------- 20150101 Mouse 10 20150101 Keyboard 100 20150202 Mouse 20 20150202 Keyboard 200 I want to query like this. Date Item BuyItem RunningTotal ------------------------------------------------------------------------- 20150101 Mouse 10 10 20150202 Mouse 20 30 20150101 Keyboard 100 100 20150202 Keyboard 200 300 Try using CROSS APPLY (BEST WAY or Correlated sub-query. ;WITH cte AS ( SELECT * (VALUES (20150101,'Mouse',10, (20150101,'Keyboard',100, (20150202,'Mouse',20, (20150202,'Keyboard',200 tc([date], Item, BuyItem SELECT * cte a CROSS APPLY(SELECT SUM(BuyItem AS running_total cte b WHERE a.item = b.item AND a.[date] >= b.[date] cs Result: Date Item BuyItem Running_Total -------------------------------------------------------------- 20150101 Mouse 10 10 20150202 Mouse 20 30 20150101 Keyboard 100 100 20150202 Keyboard 200 300
Recursive CTE method using ROW_NUMBER function and PARTITION: ;WITH cte AS (SELECT ROW_NUMBER(OVER(PARTITION BY Item ORDER BY [date] AS rn,* (VALUES (20150101,'Mouse',10, (20150101,'Keyboard',100, (20150202,'Mouse',20, (20150202,'Keyboard',200 tc([date], Item, BuyItem, CTE_RunningTotal AS (SELECT [Date],Item,BuyItem,BuyItem AS running_total,rn cte WHERE rn = 1 UNION ALL SELECT T.[Date],T.Item,t.BuyItem, T.BuyItem + C.running_total AS running_total, t.rn CTE_RunningTotal AS C INNER JOIN cte AS T ON T.Item = c.item AND t.rn = C.rn + 1 SELECT [Date], Item, BuyItem, running_total CTE_RunningTotal AS C Note: Better to update your server to 2012 which can use sum( over(order by method to calculate running total which much faster than these methods --Using CROSS APPLY: SELECT [Date], item, running_total #yourtable a CROSS APPLY(SELECT SUM(BuyItem AS running_total #yourtable b WHERE a.item = b.item AND a.[date] >= b.[date] ca ORDER BY BuyItem
--Make a use of windowing function. in SQL 2012+ DECLARE @Items TABLE ( DATE NVARCHAR(MAX, Item NVARCHAR(MAX, BuyItem INT INSERT INTO @Items([DATE], Item, BuyItem VALUES('20150101', 'Mouse', 10 INSERT INTO @Items([DATE], Item, BuyItem VALUES('20150101', 'Keyboard', 100 INSERT INTO @Items([DATE], Item, BuyItem VALUES('20150202', 'Mouse', 20 INSERT INTO @Items([DATE], Item, BuyItem VALUES('20150202', 'Keyboard', 200 SELECT [DATE], Item, SUM(BuyItem OVER (PARTITION BY Item ORDER BY BuyItem AS RunningTotal @Items ORDER BY Item DESC Result: Date Item BuyItem Running_Total ------------------------------------------------------------------- 20150101 Mouse 10 10 20150202 Mouse 20 30 20150101 Keyboard 100 100 20150202 Keyboard 200 300 In aggregate function, with running total, using Window functions are very good performance In SQL 2012+: SELECT *, SUM( OVER(PARTITION BY Item, ORDER BY [Date] AS RunningTotal Your_Table ORDER BY Item DESC --Faster than when add window frame: SELECT *, SUM( OVER(PARTITION BY Item, ORDER BY [Date] ROWS UNBOUNDED PRECEDING AS RunningTotal Your_Table ORDER BY Item DESC
Reverse Cumulative Creates a reverse cumulative (minus the cumulative column on each row to the next I have this table: id ID [Date] Cumulative ------------------------------------ 1 x Jan-10 10 3 x Feb-10 40 7 x Apr-10 60 9 x May-10 100 2 y Jan-10 20 6 y Mar-10 40 8 y Apr-10 60 10 y May-10 100 I need to Reverse the "Cumulative" in MS SQL Server Query to be as the following: id ID [Date] Cumulative Reversed ------------------------------------ 1 x Jan-10 10 10 3 x Feb-10 40 30 -- 10 40 = 30 7 x Apr-10 60 20 -- 40 60 = 20 9 x May-10 100 40 -- 60 100 = 40 2 y Jan-10 20 20 -- 40 20 = 20 6 y Mar-10 40 20 -- 20 40 = 20 8 y Apr-10 60 20 -- 40 60 = 20 10 y May-10 100 40 -- 60 100 = 40 For below SQL server 2012 using recursive CTE for reverse running total. DECLARE @t TABLE(id INT,IDs VARCHAR(20,Dates VARCHAR(20,Cumulative INT INSERT INTO @t VALUES (1,'x','Jan-10', 10,(3,'x','Feb-10', 40,(7,'x','Apr-10', 60,(9,'x','May-10', 100,(2,'y','Jan-10', 20,(6,'y','Mar-10', 40,(8,'y','Apr-10', 60,(10,'y','May-10',100
;WITH CTE AS (SELECT *,row_number(over(partition BY ids ORDER BY idrn @t,cte1 AS (SELECT id,ids,dates, Cumulative,rn,Cumulative Reversed cte WHERE rn=1 UNION ALL SELECT c.id,c.ids,c.dates,c.cumulative,c.rn,c.cumulative - c1.cumulative cte c INNER JOIN cte c1 ON c.ids=c1.ids WHERE c.rn = c1.rn+1 SELECT * cte1 You can use lag to get the value in the previous row and subtract from the current row's value to get the reversed value. SELECT t.*, Cumulative - COALESCE(lag(Cumulative OVER(PARTITION BY id ORDER BY [Date],0 AS Reversed tablename t You can use lag(cumulative,1,0 instead of coalesce. SELECT t.*, Cumulative-lag(Cumulative,1,0 OVER(PARTITION BY id ORDER BY [Date] AS Reversed tablename t
Total of Each Day of Week Gets the total of each day of the week and then organizes the information with each day of the week in columns and the total weekly sum underneath using the pivot function. ;WITH cte AS ( SELECT DATENAME(dw,releasetime as DayOfWeekName,COUNT(* OVER ( as TotalCount @release WHERE releasetime >= DATEADD(DAY,- DATEPART(dw,GETDATE( + 1,CAST(GETDATE( AS DATE AND releasetime < DATEADD(DAY,7 - DATEPART(dw,GETDATE( + 1,CAST(GETDATE( AS DATE SELECT * cte PIVOT ( COUNT(DayOfWeekName FOR DayOfWeekName IN (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday p