mysql在最后一小时选择记录,没有日期

时间:2012-06-28 17:58:44

标签: mysql datetime comparison

我有一张每日发送电子邮件的表格。所以我存储了一天中的时间,作为时间字段(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 AM之间获得所有记录。这将包括迈克的电子邮件。如果脚本在凌晨12:15(00:15)运行,它应该在11:15 PM(23:15)和12:15 AM(00:15)之间获得所有记录。这将包括corey的电子邮件。

我在every和网络上查看了example 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( )
)

我想出了一个黑客来匹配这个小时和最后一个小时,在此之前,但似乎,好吧,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( ) )
)

感谢您的帮助!

2 个答案:

答案 0 :(得分: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())
  )
);

答案 1 :(得分: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'))将当前时间截断到当前时间。它也可以很好地应对午夜翻滚。