【问题标题】:Mysql relative date subtractionMysql相对日期减法
【发布时间】:2013-08-28 19:51:36
【问题描述】:

我有以下两张表

# Event table
id    title         start_date              end_date
----------------------------------------------------------
1      Foo     2013-05-06 20:30:00     2013-05-06 22:45:00
2      Bar     2013-06-03 07:40:00     2013-05-06 10:45:00
3      Demo    2013-05-02 00:22:00     2013-05-06 03:45:00
4      Test    2013-07-09 10:56:00     2013-05-06 13:45:00

# Notification table
id   event_id         mail         time    type     sent
----------------------------------------------------------
1       1       123@example.com     15    minute     0
2       1       234@example.com     01    day        0
3       3       655@example.com     01    week       0
4       4       888@example.com     40    minute     0
5       4       999@example.com     42    minute     1
5       4       987@example.com     30    minute     0

cron 作业每分钟执行一个 PHP 脚本,以检查是否应将通知发送到通知表中的电子邮件地址。时间值是应该发送提醒的事件开始日期之前的相对时间。

例如,当 cron 作业在 2013-05-06 20:15:00 运行时,应向电子邮件地址 123@example.com 发送一封电子邮件。还应考虑发送标志。如果将其设置为 0,则所有通知也应在低于发送日期的情况下发送。例如,当 cron 作业在 2013-07-09 10:26:00 运行时,应将邮件发送到 987@example.com888@example .com.

我的问题是,查询在 mysql 中的外观如何才能获取通知以满足实际 (now()) 日期的上述要求?我尝试使用date_sub,但并没有真正成功。非常感谢您的帮助。

【问题讨论】:

  • 很难说,但却是事实。在通知表中保留类型是一种丑陋的数据库设计
  • 什么是更好的方法?你的评论真的没有帮助!!
  • 将所有类型保存在一个查找表中,并将其引用保存在通知表中,可以加快余额时间的动态计算

标签: php mysql sql select join


【解决方案1】:

据我所知,这个问题有两个部分。一是将不同的单位转换为时间比较。另一个是确保只发出一个通知。

第一个可以通过一个大的case 语句来处理。第二个可以通过检查时间间隔来处理,而不是不等式:

. . .
from event e join
     notification n
     on e.id = n.event_id
where (case when n.type = 'minute'
            then now() - interval n.time minute <= e.start_date and
                 now() + interval 1 minute - interval time minute > e.start_date
            when n.type = 'day'
            then now() - interval n.time day <= e.start_date and
                 now() + interval 1 minute - interval time day > e.start_date
            when n.type = 'week'
            then now() - interval 7*n.time day <= e.start_date and
                 now() + interval 1 minute - interval 7*time day > e.start_date
            when n.type = 'month'
            then now() - interval n.time month <= e.start_date and
                 now() + interval 1 minute - interval time month > e.start_date
       end) > 0 and sent = 0;

而且,正如 Tom 指出的那样,最好为每个通知设置一个已发送标志,而不是取决于特定时间。作业可能因各种原因而延迟。

【讨论】:

  • 戈登,你有一些语法错误。您使用 date_sub 几次,但也在添加/减去间隔。另外,您还有几个额外的结尾括号。
  • 另外,使用发送标志而不是使用日期范围不是更好吗?
  • @Tom 。 . .感谢您的编辑。至于你的第二条评论,我完全同意。取决于特定的时间范围在大多数环境中可能是危险的。
  • 发送的 falg 存在,但未在您的解决方案中使用。还是我错过了什么?
  • 您必须将 now() - 间隔 n.time 月 更改为 now() + 间隔 n.time 月,因为 now 需要在开始日期之前。这是加法,没有减法。请接受我的修改。
猜你喜欢
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-21
  • 2020-07-26
  • 1970-01-01
相关资源
最近更新 更多