MySQL日期重复

时间:2013-07-01 11:13:46

标签: php mysql sql date

在我的一个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个月的间隔

实际上这是否是出于此目的的正确方法?或者我需要改变表格?

任何人都可以给我一个想法吗? 提前致谢

5 个答案:

答案 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