[英]PHP/MySQL: Model repeating events in a database but query for date ranges
我正在研究(我打算成为的)简单的PHP / MySQL应用程序。 作为其中的一部分,我希望能够为重复事件建模,但是我需要能够查询两个日期之间发生的所有事件(包括重复事件)。 事件只有一个日期,一天中的时间无关紧要。
我一直在研究这个并且已经研究了各种方法,包括日历重复/重复事件 - 最佳存储方法和重复日历事件以及一些最终数学 。
但是,我在网上找到的支持这种情况的数据库模式的任何示例似乎都支持查询某一天发生的事件。 不支持在一系列日期之间发生的事件。
作为一个抽象的例子
事件表(带有某种重复表示):
Event | Start Date | Repeats
-------------------------------------
Meeting | 10/Dec/2012 | Every 7 days
Lunch | 10/Dec/2012 | Every 1 days
抽象查询的目标结果SELECT Events BETWEEN 09/Dec/2012 AND 20/Dec/2012
Event | Date | Repeats
-------------------------------------
Meeting | 10/Dec/2012 | Every 7 days
Meeting | 17/Dec/2012 | Every 7 days
Lunch | 10/Dec/2012 | Every 1 days
Lunch | 11/Dec/2012 | Every 1 days
Lunch | 12/Dec/2012 | Every 1 days
Lunch | 13/Dec/2012 | Every 1 days
etc...
Lunch | 20/Dec/2012 | Every 1 days
是否有支持这类查询的数据库架构? 如何在两天之间发生的任何事件(包括重复事件)对该模式进行查询?
或者也许是用于重复事件的设计模式?
我将使用一个名为id
col创建一个计数表,并用0到500的数字填充该表。现在我们可以轻松地使用它来进行选择而不是使用while循环。
Id
-------------------------------------
0
1
2
etc...
然后我将事件存储在一个表中,其中Name as varchar
, startdate as datetime
, repeats as int
Name | StartDate | Repeats
-------------------------------------
Meeting | 2012-12-10 00:00:00 | 7
Lunch | 2012-12-10 00:00:00 | 1
现在我们可以使用计数表来选择两个日期之间的所有日期:
SELECT DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY) as showdate
FROM `tally`
WHERE (DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY)<='2012-12-20 00:00:00')
ORDER BY Id ASC
ShowDate
-------------------------------------
2012-12-09 00:00:00
2012-12-10 00:00:00
2012-12-11 00:00:00
2012-12-12 00:00:00
2012-12-13 00:00:00
2012-12-14 00:00:00
2012-12-15 00:00:00
2012-12-16 00:00:00
2012-12-17 00:00:00
2012-12-18 00:00:00
2012-12-19 00:00:00
2012-12-20 00:00:00
然后我们在事件表上加入它来计算startdate和showdate之间的差异。 我们通过repeats
列将结果分开,如果余数为0
,我们匹配。
所有组合成为:
SELECT E.Id, E.Name, E.StartDate, E.Repeats, A.ShowDate, DATEDIFF(E.StartDate, A.ShowDate) AS diff
FROM events AS E, (
SELECT DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY) as showdate
FROM `tally`
WHERE (DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY)<='2012-12-20 00:00:00')
ORDER BY Id ASC
) a
WHERE MOD(DATEDIFF(E.StartDate, A.ShowDate), E.Repeats)=0
AND A.ShowDate>=E.StartDate
结果如何
Id | Name |StartDate | Repeats | ShowDate | diff
---------------------------------------------------------------------------------
1 | Meeting | 2012-12-10 00:00:00 | 7 | 2012-12-10 00:00:00 | 0
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-10 00:00:00 | 0
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-11 00:00:00 | -1
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-12 00:00:00 | -2
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-13 00:00:00 | -3
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-14 00:00:00 | -4
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-15 00:00:00 | -5
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-16 00:00:00 | -6
1 | Meeting | 2012-12-10 00:00:00 | 7 | 2012-12-17 00:00:00 | -7
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-17 00:00:00 | -7
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-18 00:00:00 | -8
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-19 00:00:00 | -9
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-20 00:00:00 | -10
现在你可以(并且应该!)加快速度。 例如,通过直接在表中存储日期,您可以直接选择所有日期,而不是使用带有dateadd的计数表。 你可以缓存并且不必再次计算的每件事都很好。
我不太明白你的目标......也许你在SQL中寻找UNIQUE函数?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.