0

行ユーザーをデータベースに行として保存しています。ユーザーが自分のタイムゾーンを入力できるようにしています。これはデータベースにも保存されます。

私のアプリは、指定された時間に毎日メールを送信します。メール配信を別の db テーブルに行として保存します。これは、cron ジョブを介して行われます。

タイムゾーンに従って、そのユーザーの最新の電子メールが少なくとも 1400 分 (24 時間前) であり、指定された時間を過ぎたユーザー レコードをクエリで取得したいと考えています。

次のクエリがありますが、mysql のタイムゾーンとユーザーのタイムゾーンを考慮する方法がわかりません。助言がありますか?

SELECT u.id, u.email, u.timezone_offset, u.email_time, TIMESTAMPDIFF( 
MINUTE , CONCAT( DATE( MAX( e.created ) ) ,  ' ', u.email_time ) , NOW( ) ) AS min_since_last_email
FROM Users u
INNER JOIN Emails e ON e.user_id = u.id
WHERE min_since_last_email > 1400
GROUP BY u.id

タイムゾーンのオフセットは GMT からのオフセットなので、私にとっては「-5」のようなものになります。

4

2 に答える 2

0

ロジックを少し変えてください。PHPで計算を行い、すべてをUTCでデータベースに保存します。次に、それは単純な抽出です。これは、タイムゾーン関数を使用してPHPで簡単に行うことができ、ユーザーごとにカスタマイズできます。SQLステートメントは、ユーザーごとにカスタマイズするのが難しいグローバルステートメントです(経験上)。

したがって、「電子メールの送信時刻」はUTCの午前4時(およびデータベースにあります)である可能性がありますが、ユーザーには「午後9時」と表示されます。

あなたが抱えているかもしれない問題の1つは夏時間です-タイムゾーンが夏時間に出入りするとき、あなたはいつも再計算する必要があるでしょう。しかし、あなたは現在の方法ではとにかくこれを許可していません...

于 2012-09-11T01:20:10.357 に答える
0

最後にメールを送信した日付があなたの日付になりますので、それを保管してください。

より多くの電子メールを送信するにつれて、ユーザーあたりの最大値を計算すると、ますますコストがかかります。その日時のコピーを非正規化して、ユーザー レコードにも入れます。

次に、その日付の年齢とユーザーのタイムゾーンのオフセットを計算します。

select *, date_add(now(), interval timezone_offset hour) as email_expected_on
from users
where last_email_date <= date_add(now(), interval timezone_offset hour);

users.last_email_date に式を適用しないことも重要であることに注意してください。そうしないと、その列でインデックスを使用できなくなります。

于 2012-09-11T01:29:06.540 に答える