我正在創建一個程序,其中主要功能是事件日曆。數據庫中有人員和事件,並跟蹤參加個別事件。使用重複間隔生成日期列表
在事件方面,我希望能夠提供重複生成事件的選項。如果事件被重複,用戶提供了以下信息:
1)事件的開始日期 2)活動的結束日期 3)重複天數(例如,四) 4)重複間隔(每週,雙週,和每月)
所有這些信息被插入到一個表,「事件」,然後導致觸發器執行。觸發器使用此信息在另一個表「event_instances」中生成記錄,該表包含給定事件(事件發生的每一天)的每個實例的記錄。然後根據每個實例跟蹤事件出席情況。
爲了最大限度提高性能,我一直在創建一個臨時表的方法,將其過濾爲只有我需要的日期,然後將其插入到event_instance表中。這是一個很好的方法,因爲它能夠在1-2秒內完成整個操作。
我的問題現在歸結爲重複間隔。在我去那裏之前,這裏是我用來生成臨時表的sql代碼。此公式會在@start_date和@end_date之間創建一個包含100,000個日期的表格。 @start_date和@end_date是臨時值,在最後的實現中,這將是一個帶有兩個日期參數的函數。
set @start_date = '2015-9-20';
set @end_date = '2016-1-17';
select * from
(select @start_date + interval ((a.a) + (10 * b.a) + (100 * c.a) + (1000 * d.a) + (10000 * e.a)) day this_date
from
(select 0 as a
union all select 1
union all select 2
union all select 3
union all select 4
union all select 5
union all select 6
union all select 7
union all select 8
union all select 9) as a
join
(select 0 as a
union all select 1
union all select 2
union all select 3
union all select 4
union all select 5
union all select 6
union all select 7
union all select 8
union all select 9) as b
join
(select 0 as a
union all select 1
union all select 2
union all select 3
union all select 4
union all select 5
union all select 6
union all select 7
union all select 8
union all select 9) as c
join
(select 0 as a
union all select 1
union all select 2
union all select 3
union all select 4
union all select 5
union all select 6
union all select 7
union all select 8
union all select 9) as d
join
(select 0 as a
union all select 1
union all select 2
union all select 3
union all select 4
union all select 5
union all select 6
union all select 7
union all select 8
union all select 9) as e) v
where this_date <= date(@end_date);
這會生成一個表,其中包含@start_date和@end_date之間的每個日期。要縮小到每週重複是容易的,我需要做的就是添加(每週星期四的例子):
and dayofweek(this_date) = 5
的事情是,我無法弄清楚如何做到每兩週或每月從這裏過濾。這是所有這些工作的最後一部分。
非常感謝。
這是一個衆所周知難以解決的難題。閱讀這本書。 http://www.worldcat.org/title/dreaming-in-code-two-dozen-programmers-three-years-4732-bugs-and-one-quest-for-transcendent-software/oclc/70174970 –