选择7天内到期的所有日期

时间:2016-11-24 11:29:32

标签: mysql

我有以下查询(不起作用):

SELECT user_id FROM due_dates WHERE due_date < DATE_ADD(CURDATE(),INTERVAL 1 WEEK)

我想在1周内选择due_date到期的所有user_id。

我的脚本有什么作用?

它会发送一封类似于&#34的电子邮件;您的帐户将在7天内到期&#34;。

任何人都知道如何解决这个问题?

3 个答案:

答案 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_dateDATE类型:

SELECT user_id
  FROM due_dates
 WHERE due_date = CURDATE() + INTERVAL 1 WEEK

如果due_date是另一个时间(DATETIMETIMESTAMP):

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(),则会返回该行。

这是一个微妙但重要的区别。