我的任务是向我们数据库中的客户发送电子邮件提醒,通知他们的年度订阅即将到期。发送期限为账户过期前30天、15天、7天。已经发送的邮件直到下一个时间段才会重新发送(例如 john.doe@aaa.com 帐户将在 2012-06-01 到期。服务器在 2012-05-02 发送电子邮件,然后等到 2012-05 -17 如果状态没有改变,则再次发送)。此外,如果 account_status.statusId 不是 3,服务器将不会再次发送消息并将 account_metadata.v 设置回 7。
下面的示例数据列表:
帐户
id email
1 velit@necenimNunc.com
2 nec@magna.org
3 imperdiet.ullamcorper.Duis@sagittisaugue.com
4 lacus@velitin.edu
5 Curae;@Phasellus.edu
6 dui.nec@Vivamussitamet.org
7 Aliquam.erat.volutpat@Intincidunt.com
8 vehicula.risus.Nulla@id.org
9 Fusce.diam.nunc@egetdictum.ca
10 urna@magnaNam.edu
11 vitae.erat@erategetipsum.ca
12 eu@eratneque.com
13 non@inconsectetuer.com
14 lectus@Nullamfeugiat.ca
15 sit.amet.diam@enimEtiamimperdiet.com
16 consectetuer.euismod.est@euerosNam.com
17 urna.Nunc.quis@egestas.com
18 tristique.aliquet.Phasellus@afelis.org
19 eget.tincidunt.dui@ligula.org
20 primis.in@accumsanneque.edu
21 ultricies.adipiscing@arcuVestibulum.com
22 euismod.et.commodo@nisi.edu
23 iaculis.quis@molestietortornibh.com
24 molestie@Pellentesque.org
25 ligula.tortor.dictum@dolor.com
26 dictum.ultricies.ligula@ipsum.com
27 pretium@turpis.ca
28 neque.Nullam.nisl@feugiatLoremipsum.edu
29 adipiscing.non.luctus@inconsequatenim.ca
30 faucibus@Mauris.com
帐户状态
id statusId accountId time
1 1 2 2011-06-01 21:54:37
2 1 3 2011-06-02 09:07:14
3 1 4 2011-06-02 09:13:20
4 1 5 2011-06-02 09:54:44
5 1 6 2011-06-02 10:15:52
6 1 7 2011-06-02 10:17:22
7 2 7 2011-06-02 10:21:25
8 1 8 2011-06-02 11:09:03
9 1 9 2011-06-02 11:09:18
10 1 10 2011-06-02 11:13:29
11 1 11 2011-06-02 11:21:11
12 1 12 2011-06-02 11:21:35
13 3 5 2011-06-02 11:41:04
14 3 2 2011-06-02 11:46:07
15 1 13 2011-06-02 11:49:18
16 3 13 2011-06-02 11:53:45
17 1 14 2011-06-02 12:02:26
18 3 14 2011-06-02 12:10:54
19 1 15 2011-06-02 13:41:19
20 1 16 2011-06-02 15:27:03
21 3 16 2011-06-02 15:42:58
22 1 17 2011-06-02 15:46:05
23 1 18 2011-06-02 15:59:56
24 1 19 2011-06-02 16:13:41
25 1 20 2011-06-02 16:17:36
26 1 21 2011-06-02 16:47:04
27 1 22 2011-06-02 16:47:39
28 1 23 2011-06-02 18:35:29
29 1 24 2011-06-02 19:17:06
30 1 25 2011-06-02 20:07:33
account_metadata
id accountId k v
27033 2 remindEmail 3
27034 3 remindEmail 3
27035 4 remindEmail 3
27036 5 remindEmail 3
27037 6 remindEmail 3
27038 7 remindEmail 3
27039 8 remindEmail 3
27040 9 remindEmail 7
27041 10 remindEmail 7
27042 11 remindEmail 7
27043 12 remindEmail 7
27044 13 remindEmail 3
27045 14 remindEmail 3
27046 15 remindEmail 7
27047 16 remindEmail 3
27048 17 remindEmail 7
27049 18 remindEmail 7
注意:
accounts.id
并且account_metadata.accountId
是独一无二的accounts.id = account_metadata.accountId = account_status.accountId
- 这三个表都是 Innodb
我目前拥有的 MySQL 查询是:
如果 account_status 中的 statusId 不为 3,则将提醒邮件的值设置为 7:
UPDATE `account_status` AS acs, `accounts` AS a, `account_metadata` AS am SET am.v = '7' WHERE acs.statusId != 3 AND acs.accountId = a.id AND a.id = am.accountId AND am.k = 'remindEmail';
已发送电子邮件提醒取决于 1 年前的时间段(30 天 => 7、15 天 => 3、7 天 => 1)和
status = 3
:SELECT am.accountId, a.email, am.k, am.v, acs.time FROM accounts a INNER JOIN account_status acs ON a.id = acs.accountId INNER JOIN account_metadata am ON a.id = am.accountId WHERE acs.statusId = 3 AND am.k = 'remindEmail' AND NOW() <= DATE_ADD(acs.time, INTERVAL 365 DAY) AND NOW() > DATE_ADD(acs.time, INTERVAL 365 - ((am.v & 1) * 7 + (am.v & 2) * 8 + (am.v & 4) * 15) DAY) AND am.v = %s;
更新
account_metadata.v
到新状态:UPDATE `account_metadata` AS am SET am.v = '%s' WHERE am.accountId = '%s' AND am.k = 'remindEmail';
这里的问题是,account_status.accountId
不是唯一的(见上表 where accountId = 13
)。这将导致#1 将一些行重置为 7,并且客户会觉得他们收到了垃圾邮件。有什么方法可以修改 #2 和/或 #1 以选择最新的account_status.statusId
(基于account_status.time
)或通过最新的更新account_status.stautsId
?