表格包含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
如果日期是05/16/2013,则查询会按预期返回$ 50.00。
现在,用户需要添加一个必须采用最高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
答案 0 :(得分: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
我在这里假设有关你的架构的一些事情,但我认为这应该可以帮助你开始。
答案 1 :(得分:1)
这是基于我想要使用EffectiveDate的想法的猜测:
select top 1 price
where :pDate between coalesce(EffectiveDate, ValidFrom) and ValidTo
order by coalesce(EffectiveDate, ValidFrom) DESC, Price
或者,如果有可用的有效日期,您是否想简单地抛弃所有的ValidXXX日期?
我通常建议使用min / max或ranking函数来获取价格,而不是巧妙地使用order子句操纵非ANSI top
,但这只是一个意见。
我必须承认,这个EffectiveDate
乍一看似乎有些迟钝,无法正确清理ValidFrom / To日期,例如“我们不想花时间纠正我们的数据,只是让这个价格现在正好!“因此,什么阻止EffectiveDates变得过多,使您看起来需要添加ReallyEffectiveDate
列? “有效”和“有效”这两个词在这里看起来像是同义词,对于理解和编程可能会非常混乱。好的,充满假设的咆哮。