2

我有一张要发送的每日电子邮件表。所以我将一天中的时间存储为时间字段(00:00:00,没有日期)。几个示例行可能是:

mike, timeOfDay = 07:03 meaning "send mike an email daily at 7:03AM"
corey, timeOfDay = 23:30 meaning "send corey an email daily at 11:30PM"

在任何给定时间,我都想查找过去一小时内要发送的电子邮件。例如,如果我在早上 7:55 运行它,它应该会在早上 6:55 到早上 7:55 之间获取所有记录。这将包括迈克的电子邮件。如果脚本在上午 12:15 (00:15) 运行,它应该获取 11:15PM (23:15) 和 12:15AM (00:15) 之间的所有记录。这将包括 corey 的电子邮件。

我查看了SO和网络上的每个 示例,除了小时之外,它们似乎都需要日期。

尽可能接近:

SELECT
  `notification`. *,
  now() as now,
  DATE_SUB( NOW( ) , INTERVAL 1 HOUR ) as 1hourAgo
FROM `notification`
WHERE (
  `notification`.`timeofday` > DATE_SUB( NOW( ) , INTERVAL 1 HOUR )
)
AND (
  `notification`.`timeofday` < NOW( )
)

我想出了一个 hack 来匹配这个小时和最后一个小时,在现在之前,但它看起来,嗯,hackish。必须有正确的方法来做到这一点!

这是我的黑客。

SELECT
  `notification`. * ,
  HOUR( NOW( ) ) AS HOUR ,
  HOUR( DATE_SUB( NOW( ) ,
  INTERVAL 1 HOUR ) ) AS 1hourago,
  time( now( ) ) AS now
FROM `notification`
WHERE (
     HOUR( `notification`.`timeofday` ) = HOUR( NOW( ) )
  OR HOUR( `notification`.`timeofday` ) = HOUR( DATE_SUB( NOW( ) , INTERVAL 1 HOUR ) )
)
AND (
  `notification`.`timeofday` < TIME( NOW( ) )
)

谢谢你的帮助!

4

2 回答 2

2

假设您将timeofday字段保存为TIME,您可以使用:

SELECT
  `notification`.*,
  TIME(NOW()) AS right_now,
  TIME(DATE_SUB(NOW(), INTERVAL 1 HOUR)) AS one_hour_ago
FROM `notification`
WHERE (
  HOUR(NOW()) != 0
  AND `notification`.`timeofday` BETWEEN TIME(DATE_SUB(NOW(), INTERVAL 1 HOUR)) AND TIME(NOW())
) OR (
  HOUR(NOW()) = 0
  AND (
       `notification`.`timeofday` BETWEEN TIME(DATE_SUB(NOW(), INTERVAL 1 HOUR)) AND '24:00'
    OR `notification`.`timeofday` BETWEEN '0:00' AND TIME(NOW())
  )
);
于 2012-06-28T18:23:34.683 回答
0

你没有说你的 timeofday 字段存储在什么数据类型中。我假设它是一个TIME字段。

当您说“从最后一小时开始”时,大概是指“从前一小时开始到刚刚结束的一小时结束之前的时间”。也就是说,例如,如果您在 10:03 运行此程序,您希望时间在 9:00(含)到 10:00(不含)的范围内。

这就是你要做的。

SELECT TIME(TIME_FORMAT(n.timeofday,'%H:00:00')) as hour, n.whatever, n.whatelse
  FROM `notification` as n
 WHERE n.timeofday >= TIME(DATE_FORMAT(NOW() - INTERVAL 1 HOUR, '%H:00:00'))
   AND n.timeofday <  TIME(DATE_FORMAT(NOW(), '%H:00:00'))

如果您在 timeofday 表上放置索引,即使您的通知表中有很多行,这也将具有良好的性能。

如果您要投入生产,那么任何对当前时刻的依赖都是一个坏主意:各种批处理作业、事件和 cronjobs 不会真正地、永远地在您告诉它们的那一刻运行。如果您在运行每小时工作时遵循依赖当前时刻的策略,您有时会发送额外的消息或错过一些消息。这就是为什么您应该考虑使用TIME(DATE_FORMAT(NOW(),'%H:00:00'))将当前时间截断为当前时间的原因。它还可以很好地应对午夜翻转。

于 2012-06-28T18:19:31.537 回答