2012-06-28 98 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

相關問題