2013-03-07 103 views
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的工作,並且它運行良好(或者我認爲)通過發送電子郵件給所有在一年前購買會員的會員。但是,我沒有考慮到會員可以在我的腳本發出自動提醒之前更新其成員的事實)。

**更新: 在試圖實施該解決方案的幾個你推薦(THANK YOU!),這是我現在有我的查詢:

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往往會打破我的邏輯(這是我的頭),因爲我的store_transactions表具有不同類別的交易,可以由同一個成員(即會員,活動門票,廣告,捐贈等)。爲了這個查詢的目的,我只關心查看成員類別事務(「categoryID = 1」)。額外的「lifetime!='Y'」禁止此查詢返回其成員資格永不過期的終生成員。

總之,我希望此查詢返回一年前擁有「categoryID = 1」事務的成員的記錄,除非他們有「categoryID = 1」的更近期事務。下面是我的store_transactions表中的字段的情況下,它可以幫助:

ID 發票 MEMBERID 的categoryID 的productID 名 價格 數量 dateModified addedBy

+1

因此,如果有人做一個次要購買它將在同一個表中?然後你可以選擇'MAX(store_transactions.dateModified)' – Horen 2013-03-07 22:17:14

+0

謝謝Horen。我相信你的提示很好,但我在執行時遇到問題(見下文)。另外,我會更新我的代碼以顯示最新內容。 – psterling 2013-03-17 15:31:02

回答

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) 

我簡化了一下,但你應該得到正確的想法。

編輯:

您可以同時使用WHEREHAVING。在GROUP BY之前的地方,並過濾符合或不符合條件的單個行。具有條款包括對這些組的彙總。

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) 
+0

謝謝你的幫助 - 我對我的延遲響應道歉!我覺得這幾乎是我的正確解決方案,但是在HAVING之前(而不是在WHERE之後)放置GROUP BY members.id會破壞我的邏輯。雖然所有交易都記錄在一張表中,但它們可以是不同的類別(會員可以在一次交易中購買會員資格,廣告,活動門票等)。我只想看看'會員'交易,但通過在HAVING之前使用GROUP BY members.id,它忽略了每個會員不同類別的可能性。這是一個簡單的修復? – psterling 2013-03-17 15:29:49

+0

檢查我的答案中的編輯,我認爲這是你想要的。 – JodyT 2013-03-17 16:58:42

+0

謝謝你JodyT!您的解決方案正是我所需要的 - 在此過程中我學到了一些新的MySQL技巧!我唯一需要改變的就是用'>'代替'=',這樣它只會從一個日期返回結果。謝謝!!我會投你的答案,但我想我仍然有一個「壞」的聲譽! – psterling 2013-03-17 23:13:16

0

也許類似

WHERE (0 in (SELECT COUNT(*) FROM store_transactions WHERE ...)) 

會工作?

+0

感謝您的建議。我會嘗試,如果我不能讓另一種方法工作... – psterling 2013-03-17 15:43:05

0

替代的想法,但我想我更喜歡JodyT的日期(MAX(dateModified))方法:

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

(其中pk是你的桌子上一些獨特的鍵)

+0

感謝您的建議。如果我無法讓JodyT的方法工作,我會嘗試... – psterling 2013-03-17 15:43:22