我从这个问题中得到了下一个问题:Comparing date ranges
比较两个范围的解决方案是查询:
SELECT * 从期间 哪里没有(range_start> @check_period_end OR range_end< @check_period_start)
我有更多问题。我允许人们进入一系列时期。确切地说,他们输入一个持续时间(即1周)和一系列开始日期(即5月的前2周),我必须找出他们指定的范围内是否有一周的时段。
天真的解决方案是在我的范围内每天运行上述查询。所以 - 要检查一个月范围内的3天时段,我必须运行30个查询。有更有效的方法吗?
奖励积分 - 我正在使用Django。使用Django ORM有一个很好的解决方案吗?
编辑 - 为了简化问题,我想我已经把它变成了另一个问题!我的实际问题是找到“自由空白”。我认为这会使下面的一些“纯SQL”方法无效。我认为start a new question是明智的,而不是混淆这个。其他人可能会发现这个问题在目前的形式中是有用的。
答案 0 :(得分:1)
这不适合SQL。
但是,在Django中,您可以从许多SQL约束中解脱出来。
首先,在您的模型中定义一个方法函数,在Python中定义您想要的函数。
例如
class MyThing( models.Model ):
startDate = models.DateField(...)
duration = models.IntegerField(...)
def isInside( self, aDate, aDuration ):
return aDate >= self.startDate and aDate+aDuration <= self.startDate+self.duration
然后使用您的isInside()
方法来限定对象。这将在Python中完成一些工作,它比在SQL中使用它简单得多。
为此类复杂查询定义自定义管理器。您将扩展基本的query_set方法以包含与此类似的逻辑。
for thing in MyThing.objects.filter( startDate__gte=aDate, startDate__lte=aDate+duration ):
if thing.isInside( aDate, duration ):
return thing
这将使用SQL来获取对象的子集,其中日期应包含您要查找的间隔。然后,您可以从该列表中选择最终对象的间隔。
答案 1 :(得分:1)
问题比初看起来更简单,因为用户没有直接在他们的标准中指定结束日期。
SELECT * FROM periods p
WHERE p.range_start >= @min_start
AND p.range_start <= @max_start
AND DATE_ADD(p.range_start, INTERVAL @duration DAY) <= p.range_end
答案 2 :(得分:1)
您声明用户指定(举例):
然后,您声明需要“查明他们指定的范围内是否有一周的插槽”。如果我理解正确的话,我不是100%肯定,但这就是我从中得到的......
如果是这种情况,我会按照以下方式解决这个问题......
我在SQL中的解决方案是......
SELECT
*
FROM
periods
WHERE
(range_start <= @check_end)
AND (range_end >= @check_start)
AND DATEDIFF(
DAY,
CASE WHEN range_start > @check_start THEN range_start ELSE @check_start END,
CASE WHEN range_end < @check_end THEN range_end ELSE @check_end END
)
>= @required_duration-1
的修改
这假设您的示例逻辑暗示开始日期和结束日期为包含日期 ('2009年1月1日' - &gt;'2009年1月1日'重播的一天期间)
我个人更喜欢开始日期包含,结束日期独家 (“2009年1月1日” - &gt;“2009年1月2日”重播了一天的时间段)
原因是各种数学比较和操作变得更容易,但也因为它并不要求读者假设你正在使用的准确度。
答案 3 :(得分:1)
在某些情况下,创建一个获取您可能需要的所有数据的查询的速度要快几个数量级,然后在测试之前使用业务逻辑语言对这些数据进行过滤。
在我正在处理的应用程序中使用滚动平均值执行与此类似的操作时,节省了超过100倍。
答案 4 :(得分:0)
这个怎么样。
创建一个日期表,每个日历日期一行。