Reputation: 11
SQL question - Does anyone know of a way to select the second-highest value from a bounded window? I have pricing data for a set of geographies/products/weeks. I need to create a new column that, for each row, shows the second-highest price offered for a given geo/product over the past 13 weeks. I basically need to find an NTH_ROW () equivalent in ADW. Ideally, the solution would look similar to the following but identify the 2nd-highest price rather than the max (unless there was only one week of pricing registered during the 13 wks, in which case it would populate that price):
comparison_price = MAX(price) over (
PARTITION BY geography, product
ORDER BY week
ROWS BETWEEN 12 PRECEDING AND CURRENT ROW
This image shows an example of what I would want the comparison_price column to populate for each week of a specific product/geo:
I tried using an NROW() workaround, but received an error saying that the window needs to be unbounded. I've also considered creating a separate CTE but am trying to find a more elegant solution. Any thoughts?
Thanks!
Upvotes: 1
Views: 696
Reputation: 1269953
A lateral join is the way to go. I would phrase it as:
select t.*, t2.price as comparison_price
from t outer apply
(select distinct t2.price
from (select top (13) t2.*
from t t2
where t2.geography = t.geography and
t2.product = t.product
t2.week <= t.week
order by t2.week desc
) t2
order by t2.price desc
offset 1 row fetch first 1 row only
) t2;
Upvotes: 2
Reputation: 222482
I think the simplest approach might be a lateral join, and window functions:
select t.*, coalesce(x.price, t.price) as comparison_price
from mytable t
outer apply (
select *
from (
select t1.*,
row_number() over(partition by geography, product order by price desc) rn
from mytable t1
where t1.geography = t.geography and t1.product = t.product and t1.week <= t.week
order by t1.week
offset 0 rows fetch first 13 rows only
) x
where x.rn = 2
) x
Upvotes: 2