Say I have the following schema:
-- Create the dbo.Transaction table
CREATE TABLE [dbo].[Transaction] (
[TransactionId] INT NOT NULL IDENTITY,
[AccountId] INT NOT NULL,
[TransactionDate] DateTime2(7) NOT NULL,
[Amount] decimal(9,3) NOT NULL
CONSTRAINT [PK_Transaction] PRIMARY KEY ([TransactionId])
);
And the following query:
Select
AccountId,
TransactionDate,
Amount,
AverageAmount = Avg(Amount) Over (Partition By AccountId Order By TransactionDate ROWS BETWEEN 2 PRECEDING AND CURRENT ROW),
TransactionCount = Count(Amount) Over (Partition By AccountId Order By TransactionDate ROWS 2 PRECEDING),
MinimumAmount = Min(Amount) Over (Partition By AccountId Order By TransactionDate ROWS 2 PRECEDING),
MaximumAmount = Max(Amount) Over (Partition By AccountId Order By TransactionDate ROWS 2 PRECEDING),
SumAmount = Sum(Amount) Over (Partition By AccountId Order By TransactionDate ROWS 2 PRECEDING)
From dbo.[Transaction]
Order By AccountId, TransactionDate
How would I perform this query if it were contained in a UDF or stored proc, and the sliding interval (2 in this example) wasn’t known until runtime, as passed as a parameter to the UDF / stored proc? It seems SQL 2012 doesn’t permit the use of a variable here.
As you mentioned, SQL Server only supports integer literals for PRECEDING and FOLLOWING in OVER clauses.
There are two options available to you: dynamic sql and re-writing the query to not use PRECEDING
Dynamic sql is the simpliest, but I’d be careful about putting it in a UDF.
However window functions are just fancy syntax. You can re-write the query without them:
Here is another way to re-write the query as well: