在我的一个Web应用程序(PHP和MySQL)中,有一个用户事件提醒。用户可以添加下一个提醒日期,也可以设置重复间隔(即仅一次,3个月,6个月和每年)。将其保存在表格中
id | emp_id | alert_date | repeat_interval
--------+----------------+-----------------------+----------------------
1 | 124 | 2014-05-02 00:00:00 | 3
--------+----------------+-----------------------+----------------------
2 | 123 | 2014-05-02 00:00:00 | 12
--------+----------------+-----------------------+----------------------
3 | 122 | 2014-02-02 00:00:00 | 6
--------+----------------+-----------------------+----------------------
4 | 121 | 2014-07-02 00:00:00 | 0
--------+----------------+-----------------------+----------------------
5 | 124 | 2014-05-02 00:00:00 | 6
--------+----------------+-----------------------+----------------------
6 | 125 | 2014-08-02 00:00:00 | 6
--------+----------------+-----------------------+----------------------
7 | 126 | 2014-06-02 00:00:00 | 12
--------+----------------+-----------------------+----------------------
8 | 127 | 2014-05-02 00:00:00 | 3
------------------------------------------------------------------------
repeat_interval的值为
0 - One time event
3 - Every 3 months
6 - Every 6 months
12 - Yearly
现在我每天早上都有一个“cronjob”,搜索事件并向用户发送警报。我有以下MySQL查询
SELECT *
FROM alerts as al
WHERE date(al.alert_date) = DATE_ADD(CURRENT_DATE, INTERVAL 1 DAY);
这将返回tmrw的警报,我可以发送邮件。但我的问题是如何采取这些间隔?
即如果alert_date是01-05-2013并且设置重复3个月,则需要发送邮件 01-05-2013和3个月的间隔
实际上这是否是出于此目的的正确方法?或者我需要改变表格?
任何人都可以给我一个想法吗? 提前致谢
答案 0 :(得分:3)
哟可以直接更新alert_date,告知它应该被警告的下一个日期。 因此,每次执行cronjob时,都会更新所有具有repeat_interval!= 0的警报,并使用alert_date + repeat_interval个月。我想你可以使用DATE_ADD()函数来做几个月:
UPDATE alerts SET alert_date = DATE_ADD(alert_date, INTERVAL repeat_interval MONTHS) WHERE repeat_interval != 0
如果您需要存储原始日期,只需创建一个额外的列,next_alert,然后更新该日期。
答案 1 :(得分:2)
我建议您在数据库中添加另一列(例如next_alert
),告诉您下次事件发生的时间。
然后在您的cron脚本中,您只需检查next_alert
日期是否与当前日期匹配,如果是,则将next_alert
调整为next_alert + repeat_interval
当然使用特定的sql函数来添加到目前为止的月份< / p>
DATE_ADD(next_alert, INTERVAL repeat_interval MONTHS)
或使用PHP方法来实现这一目标。
答案 2 :(得分:1)
您可以再添加一列next_alert_date,该列将存储将发送警报的下一个日期,并根据设置的间隔将列值更新为下一个警报日期,您也可以使用相同的cron。添加一列可以帮助您跟踪它的启动时间,也就是您当前的alert_date列。
答案 3 :(得分:0)
您不需要添加任何字段,例如next_alert或next_date等。您可以从下面的代码中找到提醒。
只需创建一个函数并在该函数中传递日期。以下代码将为您提供该日期的结果。
CREATE TABLE `reminder` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(255) NOT NULL,
`startdate` datetime NOT NULL,
`enddate` date NOT NULL,
`kind` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
-- Dumping data for table `reminder`
--
INSERT INTO `reminder` (`id`, `title`, `startdate`, `enddate`, `kind`) VALUES
(1, 'This is reminder', '2015-06-03 19:25:44', '2015-07-21', 'weekly');
-- Query data get results for 2015-06-17 from `reminder` table
SELECT CONCAT_WS(' ','2015-06-17',TIME(startdate)) AS ReminderDateTime, title
FROM reminder
WHERE IF(
kind='daily',
((UNIX_TIMESTAMP('2015-06-17') -UNIX_TIMESTAMP(DATE(startdate))) % (1*24*60*60)=0) ,
IF(
kind='weekly',
((UNIX_TIMESTAMP('2015-06-17') -UNIX_TIMESTAMP(DATE(startdate))) % (7*24*60*60)=0) ,
IF(
kind='monthly',
DAYOFMONTH('2015-06-17')=DAYOFMONTH(startdate),
IF(
kind='quarterly',
((UNIX_TIMESTAMP('2015-06-17') -UNIX_TIMESTAMP(DATE(startdate))) % (91*24*60*60)=0) ,
IF(
kind='yearly',
DAYOFYEAR('2015-06-17')=DAYOFYEAR(startdate),
IF(
kind='',
startdate,
'0000-00-00 00:00:00'
)
)
)
)
)
) AND DATE(startdate) <='2015-06-17' AND IF(enddate<>'0000-00-00',enddate>='2015-06-17','1') ORDER BY ReminderDateTime ASC
答案 4 :(得分:0)
修改Ritesh的答案,增加半年度,并使季度任务在同一天重复,而不是91天,日期将在几个季度内变化。
创建表格
DROP TABLE IF EXISTS tbl_events;
CREATE TABLE tbl_events (
user int(11) NOT NULL,
id int(11) NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
startdate datetime NOT NULL,
enddate date NOT NULL,
kind varchar(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
向表格添加数据
INSERT INTO tbl_events VALUES
('1','1','This is daily reminder','2017-04-24 00:00:00','2020-12-31','daily'),
('1','2','This is weekly reminder','2017-04-24 00:00:00','2020-12-31','weekly'),
('1','3','This is monthly reminder','2017-04-24 00:00:00','2020-12-31','monthly'),
('1','4','This is quarterly reminder','2017-04-24 00:00:00','2020-12-31','quarterly'),
('1','5','This is yearly reminder','2017-04-24 00:00:00','2020-12-31','yearly');
查询数据从tbl_events表中获取2017-10-23的结果
SELECT user, '2017-10-23' AS Date, title
FROM tbl_events
WHERE IF(
kind='daily',
((UNIX_TIMESTAMP('2017-10-23') -UNIX_TIMESTAMP(DATE(startdate))) % (1*24*60*60)=0) ,
IF(
kind='weekly',
((UNIX_TIMESTAMP('2017-10-23') -UNIX_TIMESTAMP(DATE(startdate))) % (7*24*60*60)=0) ,
IF(
kind='monthly',
DAYOFMONTH('2017-10-23')=DAYOFMONTH(startdate),
IF(
kind='quarterly',
DAYOFMONTH('2017-10-23')=DAYOFMONTH(startdate) AND abs(MONTH('2017-10-24')-MONTH(startdate))%3=0,
IF(
kind='semiannual',
DAYOFMONTH('2017-10-23')=DAYOFMONTH(startdate) AND abs(MONTH('2017-10-24')-MONTH(startdate))%6=0,
IF(
kind='yearly',
DAYOFYEAR('2017-10-23')=DAYOFYEAR(startdate),
IF(
kind='',
startdate,
'0000-00-00 00:00:00'
)
)
)
)
)
)
) AND DATE(startdate) <='2017-10-23' AND IF(enddate<>'0000-00-00',enddate>='2017-10-23','1') ORDER BY Date ASC