In this post we will see how we can use SQL Server Windowing function in conjunction with Aggregate functions. In SQL Server 2005 Windowing (Over Clause) was supported with all Aggregate functions (Avg , Count, Min, Max and Sum) , in SQL Server 2012 it got further better with support of "Order By" Clause.
Let's look at some Query and their O/P..
Query
1. Lets Create a TransData Table, with following Schema
CREATE TABLE TransData (AcctId int, TransDate date, Amount decimal)
INSERT INTO TransData (AcctId, TransDate, Amount) VALUES
(1, DATEFROMPARTS(2011, 8, 10), 500), -- 5 transactions for acct 1
(1, DATEFROMPARTS(2011, 8, 22), 250),
(1, DATEFROMPARTS(2011, 8, 24), 75),
(1, DATEFROMPARTS(2011, 8, 26), 125),
(1, DATEFROMPARTS(2011, 8, 28), 175),
(2, DATEFROMPARTS(2011, 8, 11), 500), -- 8 transactions for acct 2
(2, DATEFROMPARTS(2011, 8, 15), 50),
(2, DATEFROMPARTS(2011, 8, 22), 5000),
(2, DATEFROMPARTS(2011, 8, 25), 550),
(2, DATEFROMPARTS(2011, 8, 27), 105),
(2, DATEFROMPARTS(2011, 8, 27), 95),
(2, DATEFROMPARTS(2011, 8, 29), 100),
(2, DATEFROMPARTS(2011, 8, 30), 2500),
(3, DATEFROMPARTS(2011, 8, 14), 500), -- 4 transactions for acct 3
(3, DATEFROMPARTS(2011, 8, 15), 600),
(3, DATEFROMPARTS(2011, 8, 22), 25),
(3, DATEFROMPARTS(2011, 8, 23), 125)
2. Now we write a Query which will partition data by AccountId and Order them by TransDate
SELECT AcctId, TxnDate, Amount,
RAvg = AVG(Amount) OVER (PARTITION BY AcctId ORDER BY TxnDate),
RCnt = COUNT(*) OVER (PARTITION BY AcctId ORDER BY TxnDate),
RMin = MIN(Amount) OVER (PARTITION BY AcctId ORDER BY TxnDate),
RMax = MAX(Amount) OVER (PARTITION BY AcctId ORDER BY TxnDate),
RSum = SUM(Amount) OVER (PARTITION BY AcctId ORDER BY TxnDate)
FROM TxnData
ORDER BY AcctId, TxnDate
GO
3. Here is the O/P of above Query
Let's look at some Query and their O/P..
Query
1. Lets Create a TransData Table, with following Schema
CREATE TABLE TransData (AcctId int, TransDate date, Amount decimal)
INSERT INTO TransData (AcctId, TransDate, Amount) VALUES
(1, DATEFROMPARTS(2011, 8, 10), 500), -- 5 transactions for acct 1
(1, DATEFROMPARTS(2011, 8, 22), 250),
(1, DATEFROMPARTS(2011, 8, 24), 75),
(1, DATEFROMPARTS(2011, 8, 26), 125),
(1, DATEFROMPARTS(2011, 8, 28), 175),
(2, DATEFROMPARTS(2011, 8, 11), 500), -- 8 transactions for acct 2
(2, DATEFROMPARTS(2011, 8, 15), 50),
(2, DATEFROMPARTS(2011, 8, 22), 5000),
(2, DATEFROMPARTS(2011, 8, 25), 550),
(2, DATEFROMPARTS(2011, 8, 27), 105),
(2, DATEFROMPARTS(2011, 8, 27), 95),
(2, DATEFROMPARTS(2011, 8, 29), 100),
(2, DATEFROMPARTS(2011, 8, 30), 2500),
(3, DATEFROMPARTS(2011, 8, 14), 500), -- 4 transactions for acct 3
(3, DATEFROMPARTS(2011, 8, 15), 600),
(3, DATEFROMPARTS(2011, 8, 22), 25),
(3, DATEFROMPARTS(2011, 8, 23), 125)
2. Now we write a Query which will partition data by AccountId and Order them by TransDate
SELECT AcctId, TxnDate, Amount,
RAvg = AVG(Amount) OVER (PARTITION BY AcctId ORDER BY TxnDate),
RCnt = COUNT(*) OVER (PARTITION BY AcctId ORDER BY TxnDate),
RMin = MIN(Amount) OVER (PARTITION BY AcctId ORDER BY TxnDate),
RMax = MAX(Amount) OVER (PARTITION BY AcctId ORDER BY TxnDate),
RSum = SUM(Amount) OVER (PARTITION BY AcctId ORDER BY TxnDate)
FROM TxnData
ORDER BY AcctId, TxnDate
GO
3. Here is the O/P of above Query