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"

いつでも、過去1時間に送信するメールを見つけたいと思います。たとえば、これを午前7:55に実行すると、午前6:55から午前7:55までのすべてのレコードが取得されます。これにはマイクのメールが含まれます。スクリプトが12:15AM(00:15)に実行される場合、11:15PM(23:15)から12:15 AM(00:15)の間にすべてのレコードを取得する必要があります。これには、coreyのメールが含まれます。

私はSOとWebですべての を見てきましたが、それらはすべて時間に加えて日付を必要としているようです。

私が来ることができる限り近く:

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( )
)

私はこの時間と最後の時間に一致するハックを今までに考え出しましたが、それはまあ、ハックっぽいようです。これを行う正しい方法が必要です!

これが私が持っているハックです。

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ます。

「最後の1時間から」と言うときは、おそらく「前の1時間の先頭からちょうど終了した時刻の直前までの時間」を意味します。つまり、たとえば、これを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テーブルにインデックスを設定すると、通知テーブルに多くの行がある場合でも良好なパフォーマンスで機能します。

本番環境に移行する場合、現時点への依存は悪い考えです。さまざまな種類のバッチジョブ、イベント、およびcronジョブは、実際には、指示した瞬間に実行されるわけではありません。1時間ごとのジョブを実行するときに現在の瞬間に依存するという戦略に従うと、余分なメッセージを送信したり、一部を見逃したりすることがあります。TIME(DATE_FORMAT(NOW(),'%H:00:00'))そのため、現在の時刻を現在の時刻に切り捨てるためにを使用することを検討する必要があります。また、真夜中のロールオーバーにもうまく対応します。

于 2012-06-28T18:19:31.537 に答える