[英]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.