如何选择记录匹配的特定日期,但仅限于最近的记录不存在?

时间:2013-03-07 22:13:08

标签: mysql date

我有一个脚本会根据他们在我们俱乐部在线商店购买会员资格的最后日期,向其会员资格即将到期的会员发送自动续订通知:

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工作运行这个脚本,它通过向一年前购买会员资格的所有会员发送电子邮件,工作得很好(或者我认为)。但是,我没有考虑到一个成员可以在我的脚本发出自动提醒之前更新其成员资格的事实。

**更新: 在尝试实施解决方案时,你们中有几个人推荐过(谢谢!),这就是我目前的查询内容:

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

我觉得这与正确的解决方案非常接近,但是由于我的store_transactions表具有不同类别的事务,因此GROUP BY倾向于破坏我的逻辑(这在我脑海中),这可以是相同的会员(即会员,活动门票,广告,捐赠等)。出于此查询的目的,我只对查看成员资格类别事务(“categoryID = 1”)感兴趣。额外的“lifetime!='Y'”禁止此查询返回其成员资格永不过期的终身成员。

总之,我希望这个查询能够在一年前返回交易为“categoryID = 1”的成员的记录,除非他们有一个“categoryID = 1”的最新事务。这是我的store_transactions表中的字段,以防它有用:

ID 发票 会员ID 的categoryID 的productID 名称 价钱 数量 dateModified addedBy

3 个答案:

答案 0 :(得分:0)

也许像

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

会起作用吗?

答案 1 :(得分: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) 

我简化了一下,但你应该得到正确的想法。

修改

您可以同时使用WHEREHAVINGGROUP 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) 

答案 2 :(得分: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是你桌子上的一些独特钥匙)