生成重复间隔的日期列表

时间:2015-09-19 19:14:41

标签: mysql sql

我正在创建一个主要功能是事件日历的程序。数据库中有人和事件,它跟踪个人事件的出席情况。

在活动方面,我希望能够提供重复生成事件的选项。如果事件重复,则用户提供以下信息:

1)活动开始日期 2)活动结束日期 3)重复的日子(例如,星期四) 4)重复间隔(每周,每两周和每月)

所有这些信息都被插入一个表格中," events"然后导致触发器执行。触发器使用此信息在另一个表中生成记录," 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

问题是,我无法弄清楚如何从这里进行双周或每月过滤。这是完成所有这些工作的最后一部分。

提前非常感谢。

1 个答案:

答案 0 :(得分:0)

对于每月,您将使用day()功能:

where day(this_date) = 5

本月5日。

对于每两周一次(每两周一次),您应该减去一些规范日期并使用mod:

where mod(datediff(this_date, '2001-01-01'), 14) = 5

一周的其中一天,每隔一周。