2012-06-28 35 views
2

我有一个每天发送电子邮件的表格。因此,我将时间存储为一个时间段(00:00:00,不含日期)。几个示例行可能是:mysql在过去一小时中选择记录,没有日期

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 AM和7:55 AM之间得到所有记录。这将包括迈克的电子邮件。如果脚本在12:15 AM(00:15)运行,它应该在11:15 PM(23:15)和12:15 AM(00:15)之间获得所有记录。这将包括Corey的电子邮件。

我看过everyexampleSO和网络,他们似乎都需要一个日期除了小时。

尽可能靠近我可以来:

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

假设您保存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()) 
) 
); 
+0

谢谢!我的挑战是如何在不提供时间的情况下运行这种查询。我不想弄清楚如果时间超过24:00我必须包含一个OR。 – Corey

+0

@Corey我已经用更高级的查询更新了我的答案,它应该可以做你正在问的问题。 – Bart

+0

@Corey:另一个更新。这一次它是在你的数据库中量身定做的,所以如果我没有弄错,你可以使用当前的查询“按原样”。 – Bart

0

你不说你的timeofday字段存储在哪个数据类型中。我将假定它是一个TIME字段。

当你说“从最后一小时开始”时,大概你的意思是“从前一小时的顶部开始到刚刚完成的小时的顶部之前的时间。”也就是说,例如,如果你在10点03分执行此操作,你希望时间在9点到10点的范围内排除。

这就是你要做的。

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表。

如果你正在投入生产,对当下的任何依赖都是一个坏主意:各种各样的批处理作业,事件和cronjob并没有真正运行在你告诉他们的那一刻。如果您按照当前时刻的策略执行小时工任务,那么您偶尔会发送额外的消息或错过一些消息。这就是为什么你应该考虑使用TIME(DATE_FORMAT(NOW(),'%H:00:00'))截断当前时间到当前小时。它也适应午夜翻转就好了。

+0

谢谢!我补充说,它实际上是一个时间领域,并且有一些关于什么时候可能运行的例子。 – Corey

相关问题