T-SQL查询以获取商品按当前价格销售的天数

T-SQL查询以获取商品按当前价格销售的天数,sql,tsql,sql-server-2008,Sql,Tsql,Sql Server 2008,问题:列出带有最新价格(金额)和当前价格的天数的不同序号。在这种情况下, 结果: Declare @sec_temp table ( sec_no varchar(10), amount money, price_date date ) insert @sec_temp values ('123ABC', 25, '2011-01-20'), ('123ABC', 25, '2011-01-19'), ('123ABC', 25, '2011-01-18')

问题:列出带有最新价格(
金额
)和当前价格的天数的不同序号。在这种情况下,

结果:

Declare @sec_temp table 
(
 sec_no varchar(10),
 amount money,
 price_date date
)

insert @sec_temp
values
    ('123ABC', 25, '2011-01-20'), 
    ('123ABC', 25, '2011-01-19'), 
    ('123ABC', 25, '2011-01-18'), 
    ('123ABC', 20, '2011-01-15'), 
    ('123ABC', 22, '2011-01-13'),
    ('456DEF', 22, '2011-01-13')

这里有一种方法,首先查找最新价格,然后查找最后一个不同的价格:

sec_no   amount  no_of_days_at_price
123ABC   25      3                   e.g. 01-18 to 01-20
456DEF   22      1                   e.g. 01-13
最后如果所需结果实际上是介于

  • 价格等于当前价格的第一个日期;及
  • 今天
那么唯一需要改变的是:

select
 sec_no,
 amount,
 No_of_days_at_price = 1 + DATEDIFF(d, min(price_date), max(price_date))
from (
    select *,
  ROW_NUMBER() over (partition by sec_no order by price_date desc) rn,
  ROW_NUMBER() over (partition by sec_no, amount order by price_date desc) rn2
    from @sec_temp
) X
WHERE rn=rn2
group by sec_no, amount

123ABC怎么能有5天的时间?如果它延伸到当前日期,那么456DEF不应该是10天吗?如果它是20-15=5,那么456DEF应该是13-13=0吗?另一个逻辑问题,价格真的应该从“1-18”开始计算吗?IRL,价格将“保持”在20(从1-15)直到改变,对吗?@cyberwiki你是对的。它应该从“1-18”开始计数。我这边有错误,不用担心。答案经过编辑以符合更新后的要求尼斯方法。这也比目前为止的其他解决方案具有更低的查询成本。这也是错误的。在表中,当前日期不一定是该项的最后日期。@Josh-在我的两个查询中,您在哪里看到当前日期被使用?我在这两个查询中都没有看到,这就是问题所在。当前价格是在小于现在的最大(日期)生效的价格。当您将定价放入数据库时,您将其放入数据库以便在将来某个日期生效。将insert@sec_temp value('456DEF',23,'2012-01-13')添加到您的测试用例中。
sec_no  price  days_at_price
123ABC  25,00  5
456DEF  22,00  1
select
 a.sec_no,
 a.amount,
 min(price_date) as FirstDateAtPrice,
 No_of_days_at_price = COALESCE(DATEDIFF(d, c.price_date, a.price_date),0)
from (
 select *, ROW_NUMBER() over (partition by sec_no order by price_date desc) rn
 from @sec_temp) a
outer apply (
 select top 1 *
 from @sec_temp b
 where a.sec_no=b.sec_no and a.amount <> b.amount
 order by b.price_date desc
 ) c
where a.rn=1
select
 sec_no,
 amount,
 No_of_days_at_price = 1 + DATEDIFF(d, min(price_date), max(price_date))
from (
    select *,
  ROW_NUMBER() over (partition by sec_no order by price_date desc) rn,
  ROW_NUMBER() over (partition by sec_no, amount order by price_date desc) rn2
    from @sec_temp
) X
WHERE rn=rn2
group by sec_no, amount
 No_of_days_at_price = 1 + DATEDIFF(d, min(price_date), getdate())