0

クラブのオンライン ストアでメンバーシップを最後に購入した日付に基づいて、メンバーシップの有効期限が近づいているメンバーに自動更新通知を送信するスクリプトがあります。

SELECT members.id, first, last, class, email, name AS membershipType, lifetime, store_transactions.dateModified FROM store_transactions 
LEFT JOIN members ON memberID = members.id 
WHERE 
(
DATE(store_transactions.dateModified) = SUBDATE(CURDATE(), INTERVAL 1 YEAR) 
/*AND 
NOT EXISTS(SELECT * FROM store_transactions WHERE DATE(store_transactions.dateModified) > SUBDATE(CURDATE(), INTERVAL 1 YEAR))*/
)
AND categoryID = 1 AND lifetime != 'Y' 
GROUP BY members.id 
ORDER BY last, first

私は CRON ジョブを介してこのスクリプトを毎日実行しましたが、ちょうど 1 年前にメンバーシップを購入したすべてのメンバーに電子メールを送信することで、うまくいきました (またはそう思った)。ただし、スクリプトが自動リマインダーを送信する前に、メンバーがメンバーシップを更新できるという事実を考慮していませんでした)。

**更新: あなたの何人かが推奨したソリューションを実装しようとしている間 (ありがとうございます!)、現在私がクエリとして持っているものは次のとおりです:

SELECT members.id, first, last, class, email, name AS membershipType, lifetime, store_transactions.dateModified, categoryID FROM store_transactions 
LEFT JOIN members ON memberID = members.id 
GROUP BY members.id
HAVING categoryID = 1 AND lifetime != 'Y'
AND DATE(MAX(store_transactions.dateModified)) = '2012-03-24' /* specific date to simplify debugging */
ORDER BY last, first

これは正しい解決策に非常に近いと思いますが、 GROUP BY は私のロジックを壊す傾向があります (それは私の頭の中にあります)。メンバーシップ、イベント チケット、広告、寄付など)。このクエリでは、メンバーシップ カテゴリのトランザクション ("categoryID = 1") のみを調べます。追加の "lifetime != 'Y'" は、このクエリがメンバーシップの有効期限が切れない生涯メンバーを返すことを禁止します。

要約すると、このクエリでは、"categoryID = 1" のトランザクションが最近行われていない限り、ちょうど 1 年前に "categoryID = 1" のトランザクションを行ったメンバーのレコードが返されます。これが役立つ場合に備えて、store_transactions テーブルのフィールドを次に示します。

id 請求書 memberID カテゴリID productID 名前 価格 数量 dateModified addedBy

4

3 に答える 3

0

を確認してみてくださいMAX(store_transactions.dateModified)

SELECT members.id
FROM store_transactions 
LEFT JOIN members ON memberID = members.id 
GROUP BY members.id
HAVING DATE(MAX(store_transactions.dateModified)) > SUBDATE(CURDATE(), INTERVAL 1 YEAR) 

少し単純化しましたが、正しい考えが得られるはずです。

編集:

との両方WHEREを使用できますHAVING。where が の前に置かれGROUP BY、条件に一致する、または一致しない個々の行がフィルター処理されます。having 句には、グループの集計が含まれます。

SELECT members.id
FROM store_transactions
LEFT JOIN members ON memberID = members.id 
WHERE categoryID = 1 AND lifetime != 'Y'
GROUP BY members.id
HAVING DATE(MAX(store_transactions.dateModified)) > SUBDATE(CURDATE(), INTERVAL 1 YEAR) 
于 2013-03-07T22:17:18.493 に答える
0

別のアイデアですが、私は JodyT の DATE(MAX(dateModified)) メソッドを好むと思います:

WHERE pk NOT IN (SELECT pk FROM store_transactions WHERE DATE(store_transactions.dateModified) > SUBDATE(CURDATE(), INTERVAL 1 YEAR))

(pk はテーブルの一意のキーです)

于 2013-03-07T22:21:52.827 に答える