用于标识在特定时间间隔内有效的记录的SQL查询

时间:2013-04-01 18:59:21

标签: sql sql-server

我正在构建一个SQL查询,可用于获取有效日期介于给定开始/结束日期时间与生效日期永久有效的捕获之间的记录,直到有另一个具有不同生效日期的记录为止。例如,我显示的是价格表,其中产品价格根据特定日期生效

ProductID    EffectiveDate   Price
  Milk         01/01/2012     3
  Milk         02/01/2012     2.85
  Milk         03/01/2012     3.1
  Milk         03/15/2012     3.4
  Milk         04/01/2012     3.2

如果我的开始/结束日期时间是03/01和03/31,那么我想要记录03/01和03/15的记录,但是如果我的开始/结束是03/20和03/31 ,那么我需要获得03/15的记录 我的查询有效,但我试图看看是否有一种非常有效的方法来获得所需的结果。

SELECT productid, 
       effectivedate, 
       price 
FROM   product p 
WHERE  ( p.effectivedate >= '03/20/2012' 
         AND c.effectivedate <= '03/31/2012' ) 
        OR p.effectivedate = (SELECT TOP 1 pp.[effectivedate] 
                              FROM   product pp 
                              WHERE  pp.effectivedate <= '03/20/2012' 
                                     AND pp.productid = p.productid 
                              ORDER  BY pp.effectivedate DESC) 

我希望改进的原因是表格可以变得更大,我只是在这里展示一个例子作为产品,但最终表格中有更多列。

感谢您的任何建议。

2 个答案:

答案 0 :(得分:0)

这样的事情应该有效:

select somefields, max(effectivedate) maxdate
from product
where effectivedate >= @startdate
and effectivedate < @TheDayAfterEndDate
and not exists
(select *
from product
where effectivedate > @EndDate)
group by somefields

答案 1 :(得分:0)

对于这样的结构,我认为最好在结束日期中添加,然后从那里开始工作:

with BetterDataStructure as (
      select p.*,
             (select min(p2.EffectiveDate) from product p2 where p2.productId = p.productId and p2.EffectiveDate > p.EffectiveDate
             ) as EndDate
      from product p
     )
select *
from BetterDataStructure bds
where bds.startDate <= '2012-03-31' and
      (bds.endDate > '2013-03-01' or bds.endDate is NULL);

如果您使用的是SQL Server 2012,则可以使用lead()函数而不是相关子查询。