我有以下查询(不起作用):
SELECT user_id FROM due_dates WHERE due_date < DATE_ADD(CURDATE(),INTERVAL 1 WEEK)
我想在1周内选择due_date到期的所有user_id。
我的脚本有什么作用?
它会发送一封类似于&#34的电子邮件;您的帐户将在7天内到期&#34;。
任何人都知道如何解决这个问题?
答案 0 :(得分:1)
使用此查询。如果您使用 BETWEEN MySQL可以在due_date上使用索引,则它是一个完整的表扫描。
SELECT user_id
FROM due_dates
WHERE due_date BETWEEN
timestamp(date (now() -interval 1 week))
AND
timestamp(date(now() - interval 1 week + interval 1 day));
<强>样品强>
mysql> select * from due_dates;
+---------+---------------------+
| user_id | due_date |
+---------+---------------------+
| 13 | 2015-10-16 01:00:00 |
| 14 | 2015-10-16 05:00:00 |
| 15 | 2015-10-17 04:00:00 |
| 16 | 2015-10-17 05:00:00 |
| 17 | 2015-10-18 01:00:00 |
| 18 | 2015-10-19 01:00:00 |
| 19 | 2015-11-16 01:00:00 |
| 20 | 2015-11-16 05:00:00 |
| 21 | 2015-11-17 04:00:00 |
| 22 | 2015-11-17 05:00:00 |
| 23 | 2015-11-18 01:00:00 |
| 24 | 2015-11-19 01:00:00 |
| 7 | 2016-10-16 01:00:00 |
| 8 | 2016-10-16 05:00:00 |
| 9 | 2016-10-17 04:00:00 |
| 10 | 2016-10-17 05:00:00 |
| 11 | 2016-10-18 01:00:00 |
| 12 | 2016-10-19 01:00:00 |
| 1 | 2016-11-16 01:00:00 |
| 2 | 2016-11-16 05:00:00 |
| 3 | 2016-11-17 04:00:00 |
| 4 | 2016-11-17 05:00:00 |
| 5 | 2016-11-18 01:00:00 |
| 6 | 2016-11-19 01:00:00 |
+---------+---------------------+
24 rows in set (0,00 sec)
mysql> SELECT user_id
-> FROM due_dates
-> WHERE due_date BETWEEN
-> timestamp(date (now() -interval 1 week))
-> AND
-> timestamp(date(now() - interval 1 week + interval 1 day));
+---------+
| user_id |
+---------+
| 3 |
| 4 |
+---------+
2 rows in set (0,00 sec)
mysql> EXPLAIN SELECT user_id FROM due_dates WHERE due_date BETWEEN timestamp(date (now() -interval 1 week)) AND timestamp(date(now() - interval 1 week + interval 1 day));
+----+-------------+-----------+------------+-------+---------------+----------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+----------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | due_dates | NULL | range | due_date | due_date | 5 | NULL | 2 | 100.00 | Using where; Using index |
+----+-------------+-----------+------------+-------+---------------+----------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0,00 sec)
mysql>
答案 1 :(得分:0)
尝试此查询:
SELECT user_id
FROM due_dates
WHERE DATE(due_date) = DATE_ADD(CURDATE(),INTERVAL 1 WEEK)
-- if due_date is already DATE type then the following should work:
-- WHERE due_date = DATE_ADD(CURDATE(),INTERVAL 1 WEEK)
答案 2 :(得分:0)
我更喜欢更自然的速记。
如果due_date
是DATE
类型:
SELECT user_id
FROM due_dates
WHERE due_date = CURDATE() + INTERVAL 1 WEEK
如果due_date
是另一个时间(DATETIME
,TIMESTAMP
):
SELECT user_id
FROM due_dates
WHERE due_date >= CURDATE() + INTERVAL 1 WEEK
AND due_date < CURDATE() + INTERVAL 1 WEEK + INTERVAL 1 DAY
这允许优化器在due_date
上使用可用索引,并在使用包含23:59:59
时防止任何BETWEEN
混乱。
N.B。这会在进行比较之前有效地将时间转换为日期。在2000-01-08 10:00:00
NOW()
后的7天内,我们会将{_ 1}}的due_date行视为并返回。
在@ BerndBuffen的回答中,如果2000-01-01 xx:xx:xx
返回NOW()
,则该行将被过滤掉,如果2000-01-01 09:00:00
返回NOW()
,则会返回该行。
这是一个微妙但重要的区别。