在价格发生变化时查找每件商品的最新生效日期 - SQL Server 2014
Find latest effective date for each item when there is a price change - SQL Server 2014
我是 SQL Server 2014 的新手。我有一个 table,其中包含如下记录。
Year | ItemName | price | effectivefromdate
===============================================
2018 | item27 | 1595.0000 | 2017-01-01
2018 | item27 | 1595.0000 | 2018-03-01
2018 | item29 | 1000.0000 | 2017-01-01
2018 | item29 | 1100.0000 | 2018-03-01
2018 | item30 | 1795.0000 | 2017-01-01
2018 | item30 | 1795.0000 | 2018-03-01
2018 | item30 | 1795.0000 | 2018-06-01
2018 | item32 | 1322.0000 | 2017-01-01
2018 | item32 | 1350.0000 | 2018-03-01
2018 | item32 | 1376.0000 | 2018-06-01
此处每件商品都有一行或多行价格相同或不同。当价格发生其他变化时,我必须为每件商品取最近的生效日期
如果多个生效日期没有价格变化,那么我必须 return 具有最短生效日期的项目。
比如item27有两个entry但是价格没变所以我只好把price取为1595,effective date为2017-01-01
如果是item29,这里的价格有变化我得以1100为价格,生效日期为2018-03-01。
Expected Output
Year | ItemName | price | effectivefromdate
===============================================
2018 | item27 | 1595.0000 | 2017-01-01
2018 | item29 | 1100.0000 | 2018-03-01
2018 | item30 | 1795.0000 | 2017-01-01
2018 | item32 | 1376.0000 | 2018-06-01
我尝试使用 Lag/Lead 函数,但没有成功。在过去的两天里,我一直在为此苦苦挣扎。
请给我一些解决方案来解决这个问题。
您似乎想要最近价格的生效日期。
我们的想法是获取具有最终价格的行集——或者换句话说,没有不同价格且具有较大时间戳的行集。
然后聚合得到最早的生效日期:
select year, itemname, price, min(effectivefromdate)
from t
where not exists (select 1
from t t2
where t2.year = t.year and
t2.itemname = t.itemname and
t2.effectivefromdate > t.effectivefromdate and
t2.price <> t.price
)
group by year, itemname, price;
您也可以将此视为间隙和孤岛问题。然而,这可能很棘手——特别是如果价格可以随着其间的变化而重复。
您还可以使用 row_number 和分组方式,如下所示。看到一个working demo here
; with cte as
(
select *, r= row_number() over( partition by ItemName order by effectivefromdate desc) from t
)
select
t1.Year,
t1.ItemName,
t1.Price,
effectivefromdate=min(t2.effectivefromdate) from cte t1 join
t t2 on r=1 and t1.Year=t2.Year
and t1.ItemName=t2.ItemName and t1.price=t2.price
group by
t1.Year,t1.ItemName,t1.Price
通过使用 Row_Number()
:
with cte as
(
Select Year, Itemname,price,effectivefromdate,
ROW_NUMBER() over (Partition by ItemName order by price desc, effectivefromdate asc) as ranking
from tbl
)
Select Year, Itemname,price,effectivefromdate from cte where ranking = 1
注意:这仅在价格随时间上涨时有效。
我是 SQL Server 2014 的新手。我有一个 table,其中包含如下记录。
Year | ItemName | price | effectivefromdate
===============================================
2018 | item27 | 1595.0000 | 2017-01-01
2018 | item27 | 1595.0000 | 2018-03-01
2018 | item29 | 1000.0000 | 2017-01-01
2018 | item29 | 1100.0000 | 2018-03-01
2018 | item30 | 1795.0000 | 2017-01-01
2018 | item30 | 1795.0000 | 2018-03-01
2018 | item30 | 1795.0000 | 2018-06-01
2018 | item32 | 1322.0000 | 2017-01-01
2018 | item32 | 1350.0000 | 2018-03-01
2018 | item32 | 1376.0000 | 2018-06-01
此处每件商品都有一行或多行价格相同或不同。当价格发生其他变化时,我必须为每件商品取最近的生效日期 如果多个生效日期没有价格变化,那么我必须 return 具有最短生效日期的项目。
比如item27有两个entry但是价格没变所以我只好把price取为1595,effective date为2017-01-01 如果是item29,这里的价格有变化我得以1100为价格,生效日期为2018-03-01。
Expected Output
Year | ItemName | price | effectivefromdate
===============================================
2018 | item27 | 1595.0000 | 2017-01-01
2018 | item29 | 1100.0000 | 2018-03-01
2018 | item30 | 1795.0000 | 2017-01-01
2018 | item32 | 1376.0000 | 2018-06-01
我尝试使用 Lag/Lead 函数,但没有成功。在过去的两天里,我一直在为此苦苦挣扎。
请给我一些解决方案来解决这个问题。
您似乎想要最近价格的生效日期。
我们的想法是获取具有最终价格的行集——或者换句话说,没有不同价格且具有较大时间戳的行集。
然后聚合得到最早的生效日期:
select year, itemname, price, min(effectivefromdate)
from t
where not exists (select 1
from t t2
where t2.year = t.year and
t2.itemname = t.itemname and
t2.effectivefromdate > t.effectivefromdate and
t2.price <> t.price
)
group by year, itemname, price;
您也可以将此视为间隙和孤岛问题。然而,这可能很棘手——特别是如果价格可以随着其间的变化而重复。
您还可以使用 row_number 和分组方式,如下所示。看到一个working demo here
; with cte as
(
select *, r= row_number() over( partition by ItemName order by effectivefromdate desc) from t
)
select
t1.Year,
t1.ItemName,
t1.Price,
effectivefromdate=min(t2.effectivefromdate) from cte t1 join
t t2 on r=1 and t1.Year=t2.Year
and t1.ItemName=t2.ItemName and t1.price=t2.price
group by
t1.Year,t1.ItemName,t1.Price
通过使用 Row_Number()
:
with cte as
(
Select Year, Itemname,price,effectivefromdate,
ROW_NUMBER() over (Partition by ItemName order by price desc, effectivefromdate asc) as ranking
from tbl
)
Select Year, Itemname,price,effectivefromdate from cte where ranking = 1
注意:这仅在价格随时间上涨时有效。