我正在研究可能每1/2/3/4/5或6个月/年发生一次的重复事件。我在这里找到了一些解决方案,但大多数情况下都是几天/几周。
我还必须提前15天参加活动。脚本将每天在午夜运行,并检查是否有15天的事件(提醒)并发送通知(插入表格)。
这是我尝试过的查询。
SELECT *, ABS(TIMESTAMPDIFF(SECOND, first_date - INTERVAL 15 DAY, CURDATE())) AS diff,
TIMESTAMPDIFF(SECOND, first_date, first_date + INTERVAL `repeat` * IF(repeat_type = '0', 1, 12) MONTH) AS tdiff FROM reminders
WHERE
ABS(TIMESTAMPDIFF(SECOND, first_date - INTERVAL 15 DAY, CURDATE())) %
TIMESTAMPDIFF(SECOND, first_date, first_date + INTERVAL `repeat` * IF(repeat_type = '0', 1, 12) MONTH) = 0
OR ABS(TIMESTAMPDIFF(SECOND, first_date, CURDATE())) = 0;
repeat_type
确定是否每月或每年进行一次提醒(0 =每月,1 =每年)。 repeat
属性是数量(1-6)。
我认为问题在于差异(第二TIMESTAMPDIFF
)。它计算两个日期之间的差并返回秒数。但是,月份不相等(28-31天),并且由于该模数(%)有时不会返回零。我当时以为我可以用某种范围来处理这个问题(模必须返回0或<= 3天),但是我不确定什么值合适。
今天是2018年9月12日(2018-09-12)。我在表中添加了两行是由于2018-09-27,即今天起15天。
当我在上面的查询中运行时(没有where
子句),我得到了:
+----+------+------------+--------+-------------+---------+----------+----------+
| id | type | first_date | repeat | repeat_type | message | diff | tdiff |
+----+------+------------+--------+-------------+---------+----------+----------+
| 19 | 0 | 2018-09-27 | 6 | 0 | A | 0 | 15638400 |
| 20 | 1 | 2018-09-27 | 1 | 1 | AA | 0 | 31536000 |
| 21 | 2 | 2018-09-27 | 1 | 1 | AAA | 0 | 31536000 |
| 22 | 3 | 2018-09-27 | 0 | 1 | AAAA | 0 | 0 |
| 23 | 1 | 2018-03-27 | 2 | 0 | OPA | 15897600 | 5270400 |
+----+------+------------+--------+-------------+---------+----------+----------+
如果您查看最后一行(从2018-03-27开始每两个月重复一次),则该行应该在带有where
子句的结果中。
但是15897600%5270400 = 86400(也就是一天)。