需要从2个(或更多)不同的“开始日期”生成“结束日期”

时间:2019-11-02 07:19:24

标签: sql sql-server sorting date

我有一个具有ID,价格和日期的费用表。我没有“到目前为止”。因此,第一行从2019年1月1日起的item1的价格可能为50英镑,然后第二行从01/01/2020开始的item1将具有价格的55英镑。

如果我想知道今天商品1的价格,就不能使用WHERE today >= fromdate and <= todate

如何添加“ todate”?下一行的起始日期的前一天是哪里?

理想情况下需要这样做,如果可能的话,要避免创建表/存储的proc?

谢谢

2 个答案:

答案 0 :(得分:2)

要获取今天的价格,请获取最新日期不超过今天的行:

select c.price
from cost c
where c.id = 'Item1'
and c.fromdate = (
  select max(fromdate) from cost
  where id = c.id and fromdate <= getdate() 
)

或者:

select top 1 price
from cost
where id = 'Item1' and fromdate <= getdate()
order by fromdate desc

要创建todate列:

with cte as (
  select *, row_number() over (partition by id order by fromdate) rn
  from cost
)
select c.id, c.price, c.fromdate, dateadd(day, -1, cc.fromdate) todate
from cte c left join cte cc
on cc.id = c.id and cc.rn = c.rn + 1

查看简化的demo

答案 1 :(得分:1)

如彼得·施耐德(Peter Schneider)所言,明智的选择是使用窗口函数lead()为同一fromdate恢复下一条记录的id

select 
    t.*, 
    lead(fromdate) over(partition by id order by fromdate) todate
from mytable t

请注意,使用此技术,每个fromdate的{​​{1}}最高的记录将id设置为todate。如果要分配默认的结束日期,则可以使用null

您可以将其放在视图中:

coalesce()

然后您可以在视图中查询给定项目的当前价格:

create view myview as
select 
    t.*, 
    lead(fromdate) over(partition by id order by fromdate) todate
from mytable t