2

一个表具有 PriceValidFrom 、 PriceValidTo 、 BookingWindowFrom 和 BookingWindowTo 日期字段和价格货币字段。客户端随机插入或更新行。例如,某些行的 PriceValid 期限可能比其他行短,但可能在同一个月内(并且价格不同)。其他行可能具有相同的 PriceValid 期间,但可能仅在 BookingWindow 期间有所不同。桌子从来没有打扫过,一切都可以接受。我需要一个查询,给定一个日期,它将从具有最高 PriceValidFrom 日期的行返回价格。在下面的示例中,考虑表和查询语句:

PriceValidFrom PriceValidTo Price
05/01/2013     05/30/2013   $100.00
05/15/2013     05/20/2013   $50.00

伪sql

select top 1 price
where :Date between PriceValidFrom and PriceValidTo   
order by PriceValidFrom DESC, Price

如果日期是 2013 年 5 月 16 日,则查询将按预期返回 $50.00。

现在,用户需要添加一个 Booking Window 时段,该时段也必须采用最高的 BookingWindowFrom:

PriceValidFrom PriceValidTo Price     BookingWindowFrom  BookingWindowTo
05/01/2013     05/30/2013   $100.00   4/1/2013           5/30/2013 
05/15/2013     05/20/2013   $50.00    4/1/2013           5/30/2013
05/15/2013     05/20/2013   $75.00    5/1/2013           5/30/2013

现在,如果日期是 05/16/2013 并且预订日期是 5/1/2013,则查询需要返回 $75.00

如何达到预期的效果?请注意,这是一个简化的示例,但实际表中将有数百行。

select top 1 price 
where :Date between PriceValidFrom and PriceValidTo    
    and  :BookingDate  between BookingWindowFrom  and  BookingWindowTo
4

2 回答 2

1

ORDER BY不是解决方案,您必须更改您的WHERE条款。例如:

SELECT top 1 price     
WHERE EffectiveDate = :pDate
   OR (EffectiveDate IS NULL AND :pDate BETWEEN ValidFrom AND ValidTo)

ORDER BY EffectiveDate DESC, ValidFrom DESC, Price

我在这里假设有关您的架构的一些事情,但我认为这应该可以帮助您入门。

于 2013-05-01T14:58:49.160 回答
1

这是基于我认为您希望如何使用 EffectiveDate 的猜测:

select top 1 price
where :pDate between coalesce(EffectiveDate, ValidFrom) and ValidTo
order by coalesce(EffectiveDate, ValidFrom) DESC, Price

或者,如果有 EffectiveDate 可用,您是否想简单地丢弃所有 ValidXXX 日期?

我通常建议使用 min/max 或排名函数来获取价格,而不是使用 order 子句巧妙地操纵非 ANSI top,但这只是一种意见。

我必须承认,EffectiveDate乍一看,这似乎有点骇人听闻,因为无法正确清理 ValidFrom/To 日期,例如,“我们不想花时间更正我们的数据,只需立即将其设为这个价格! " 因此,是什么阻止了 EffectiveDates 变得过多并让您看起来需要添加一ReallyEffectiveDate列?“有效”和“有效”这两个词在这里似乎是同义词,理解和编程可能会非常混乱。好吧,充满假设的咆哮结束了。

于 2013-05-01T15:01:56.663 回答