Reputation:
How do I get the following result in yellow?
I want to find the maximum score over the previous year (excluding the current date) and partition by Name1 and Parent1
I've tried the following which is not giving the desired result, it just returns the max with correct partition but across all dates.
select
[VDate]
,[Name1]
,[Parent1]
,[Score]
,max(case when [VDate] > dateadd(year, -1, [VDate]) then [Score] else null end) over (partition by [Name1], [Parent1]) AS MaxScoreInPreviousLast12Months
from [dbo].[Control]
Table Data:
CREATE TABLE Control
([VDate] datetime, [Name1] varchar(10), [Parent1] varchar(10), [Score] int);
INSERT INTO Control ([VDate], [Name1], [Parent1], [Score])
VALUES
('2018-08-01 00:00:00', 'Name1', 'Parent1', 80),
('2018-07-01 00:00:00', 'Name1', 'Parent1', 85),
('2018-06-01 00:00:00', 'Name1', 'Parent1', 90),
('2017-09-01 00:00:00', 'Name1', 'Parent1', 100),
('2017-08-01 00:00:00', 'Name1', 'Parent1', 95),
('2017-07-01 00:00:00', 'Name1', 'Parent1', 70),
('2018-08-01 00:00:00', 'Name2', 'Parent2', 80),
('2018-07-01 00:00:00', 'Name2', 'Parent2', 85),
('2018-06-01 00:00:00', 'Name2', 'Parent2', 90),
('2017-10-01 00:00:00', 'Name2', 'Parent2', 60),
('2017-08-01 00:00:00', 'Name2', 'Parent2', 95),
('2017-07-01 00:00:00', 'Name2', 'Parent2', 70),
('2018-08-01 00:00:00', 'Name3', 'Parent3', 80),
('2018-07-01 00:00:00', 'Name3', 'Parent3', 96),
('2018-06-01 00:00:00', 'Name3', 'Parent3', 90),
('2017-10-01 00:00:00', 'Name3', 'Parent3', 96),
('2017-08-01 00:00:00', 'Name3', 'Parent3', 99),
('2017-07-01 00:00:00', 'Name3', 'Parent3', 105)
;
This is for SQL Server 2016+
Upvotes: 7
Views: 4997
Reputation: 1271061
Assuming you have one row per month:
select c.*,
max(score) over (partition by name1, parent1
rows between 12 preceding and 1 preceding
) as rolling_max_12
from [dbo].[Control] c;
If you don't have rows for every month, you can still solve the problem, but you data seems to have such data.
Upvotes: 0
Reputation: 1750
Something like this (a correlated subquery):
select c1.[VDate]
,c1.[Name1]
,c1.[Parent1]
,c1.[Score]
,(select max(c2.score) from [dbo].[Control] c2 where c2.Name1 = c1.Name1 and c2.Parent1 = c1.Parent1 and c2.vdate > dateadd(year, -1, c1.vdate) and c2.vdate < c1.vdate) MS
from [dbo].[Control] c1
Upvotes: 2
Reputation: 33581
Here is one way to accomplish using outer apply to a correlated subquery. Thanks for posting ddl and sample data. Made this nice and easy to work with.
select c.*
, x.MaxScore
from Control c
outer apply
(
select MaxScore = max(Score)
from Control c2
where c2.VDate < c.VDate
and c2.VDate >= dateadd(year, -1, c.VDate)
and c.Name1 = c2.Name1
and c.Parent1 = c2.Parent1
) x
Upvotes: 5