2011-11-10 15 views
0

これはSQLよりもデザインパターンの問題だと思います。イベント/時間と基準に基づくSQL

私のアプリケーションでは、ユーザーは参加して、ショップを作成し、その店舗で商品をロードできます(つまり、ユーザー、ショップ(1対1)、商品(店舗と多対1)があります)

私は時間と基準に基づいて特定の作業を行うことができるようにしたいと考えています(ただし、1回のみ)。たとえば、ユーザーに参加して1週間後に店舗がない場合、メールを送信したい場合や、ショップけどなしの製品は、電子メールなどを送信する - しかし、私は一度だけ、それをやりたいで私の頭をやっているだけ実行した後に

その - 。たとえばので、私はこのクエリ

を持っていたと言うことができます
select * from user where joineddt < '1 week ago date' 

3時間ごとに実行され、SQLを起動した後、何らかのイベント(例:電子メールを送信する)私は、このスクリプトがもう一度起動されたかどうかを確認して、すでに処理されているユーザーを拾わないようにしたい。私は「イベント」テーブルを導入することを考えました。ユーザーのイベントが一旦解消され、そのイベントのエントリが記録されますが、それは再び動作しないように見えます。たとえば「userjoined」イベントのためにできるイベントにエントリがないときに、それは結果を返しませんイベント

select * from user a 
left join event b on b.user = a.id 
where a.joineddt < '1 week ago date' 
and b.event = 'userjoined' 
and b.id is null 

、ユーザー、私は、イベント表を持っていたIDを持っていたと言う...しかし、実際にIこの 'userjoined'イベントのイベントテーブルにイベントが存在しないユーザーを返すようにしますか?

誰も私が示唆していることをする方法を考えることができますか?

答えて

1

b.idがnullの場合、b.eventは決して 'userjoined'にならないため、クエリは常に0行を返します。 'userjoined'条件をjoin句に移動します。

SELECT a.* 
FROM user a 
LEFT JOIN event b ON (b.user = a.id AND b.event = 'userjoined') 
WHERE a.joineddt < '1 week ago date' 
AND b.id IS NULL 
+0

ありがとう - 私が探していたもの! – Xrender

0

解決策を実装するために追加のテーブル(ジョインは高価です)を用意する必要はありません。あなたのユーザーテーブルでは、 'date_joined'と 'reminded'の2つのNULL可能な日付列を追加するだけです。アプリケーションのロジック(テーブル/データベース側で定義可能)は、結合の日付に 'date_joined'がデフォルトでNULLに 'reminded'されていることを確認してください。リマインダーを必要とするユーザーがピックアップする

:あなたは電子メールを送信した後に記入するようにしてください

SELECT * FROM users 
WHERE date_joined > '1 week ago' AND reminded IS NULL 

は、日付を「思い出し」。そうすれば、スクリプトの次の実行はそれを拾いません。

+0

2つのイベントは単なる例であり、多くのイベントがあり、時間が経つにつれて追加したいと思っていますが、すべてのタイプのイベントにカラムを追加することは望ましくありません。経費の面では、定期的に実行されるオフラインデーモンになりますので、影響はありません。 – Xrender

関連する問題