0

嗨,我对每天凌晨 12:00 运行的 cron 作业的 mysql 查询中的日期逻辑感到完全困惑

我正在一个汽车列表网站上工作,其中汽车列表的有效期为 mysql 日期时间格式。

所有过期的列表将在过期日期后 7 天后从网站上删除

当 cron 作业将运行时,它会执行以下操作

任务 1 - 向用户发送电子邮件警报,告诉他们他们的列表已过期。

因此,我需要选择自上次运行 cron 作业以来已过期的所有列表,并且不包括在此之前的列表,以便每个列表仅发送一次过期警报电子邮件。

我尝试执行此任务的 sql 查询(再次与此混淆)

SELECT car_id FROM cars WHERE expiry_date > DATE_SUB(NOW(), INTERVAL 1 DAY) AND expiry_date < NOW()

任务 2 - 将向用户发送电子邮件警报,告诉他们列表将在 24 小时后被永久删除。

因此,我需要选择所有将在超过 24 小时 / 6 天后删除的列表,因为它们已过期,我需要确保它们至少有 24 小时的时间来更新它们。我还需要以这样一种方式选择/构建 sql 查询,即只选择那些将在 1 天内到期而不是其他的列表,以避免多次电子邮件警报而不是一次电子邮件警报

我为此任务尝试了以下 sql 查询(我完全对这个查询感到困惑)

SELECT car_id FROM cars WHERE expiry_date > DATE_SUB(NOW(), INTERVAL 7 DAY) AND expiry_date < DATE_SUB(NOW(), INTERVAL 1 DAY)

任务 3 - 删除所有过期超过 7 天的列表

我为此任务尝试了以下 sql 查询

SELECT car_id FROM cars WHERE expiry_date < DATE_SUB(NOW(), INTERVAL 7 DAY)

请帮助我完善所有 3 个查询,以便 cron 完全按照我的意愿工作。另外请告诉我它必须>=(大于或等于)或<=(小于或等于)

这是 sqlfiddle 表结构和几条记录(尽管它们尚未过期)

http://sqlfiddle.com/#!2/cfcdf

我将非常感谢您的帮助。

4

3 回答 3

1

查看这些查询

select * from cars where datediff(EXPIRY_DATE,now())=-1;


select * from cars where 
datediff(DATE_ADD(EXPIRY_DATE, interval 24 hour),now())>=1 and
datediff(DATE_ADD(EXPIRY_DATE, interval 24 hour),now()) <=2;



select * from cars where datediff(expiry_date,now())<=-7;

操作他们正在根据您的需要工作。

小提琴 http://sqlfiddle.com/#!2/785ea/5

于 2013-02-04T06:16:23.463 回答
1

这是你想要的?请尝试添加另一列以查看两者之间的差异expiry_datecurrent date time以便您更好地了解您正在处理的日期。请查看 MYSQL 中的一些日期函数。

SQLFIDDLE 演示

-- 3rd query expiry dates older than 7 days from 
-- today

SELECT car_id, expiry_Date, 
DATE_sub(NOW(), INTERVAL 7 DAY)
FROM cars 
WHERE expiry_date <= 
DATE_sub(NOW(), INTERVAL 7 DAY)
;

-- same

SELECT car_id, expiry_Date, 
DATE_ADD(NOW(), INTERVAL -7 DAY)
FROM cars 
WHERE expiry_date <= 
DATE_ADD(NOW(), INTERVAL -7 DAY)
;


-- 2nd query going to expire in exactly 1 day

SELECT car_id, expiry_date, 
Now() + interval 1 day
FROM cars 
WHERE expiry_Date = Now() + interval 1 day
;

-- 1st query: expired 

SELECT car_id FROM cars 
WHERE expiry_date < Now()
;

-- 1st query: expired last 24 hours

SELECT car_id,DATEDIFF(expiry_date, Now())
FROM cars 
WHERE expiry_Date < Now()
AND expiry_Date >= Now() - interval 1 day
;
于 2013-02-04T06:17:57.523 回答
0

您的查询没有什么明显的问题,如果您不了解您使用的功能,请搜索它们并阅读它们,直到您了解为止。

您的方法存在一个基本问题,因为它依赖于 cron 作业以 24 小时的间隔运行-到毫秒 - 否则会出现双重上升和/或遗漏。

您需要另一个表来存储您的批处理程序上次运行时间的详细信息;用过去很长一段时间的日期用 1 行来初始化它,这样我们就有了一个起点。

您可以通过 获取最新批次SELECT MAX(date_ran) FROM BatchRecordTables。将其存储在局部变量 T0 中。获取当前时间,将其存储在局部变量 T1 中(不要在多个查询中使用 NOW(),因为它们的时间会略有不同,您需要它们相同)。我不知道这是 MySQL 的语法——你必须查一下。

然后你的情况就变成了。

  1. 向自上次运行 cron 作业以来列表已过期的人发送电子邮件,即SELECT car_id FROM cars WHERE Expiry_Date BETWEEN T0 AND T1。这只会选择列表在这批和上一批之间过期的人。
  2. 对于第二种情况,我们需要知道这些人收到了第一封电子邮件,即他们的列表在最后一批运行之前SELECT car_id FROM cars WHERE Expiry_Date BETWEEN DATE_SUB(T1, INTERVAL 6 DAY) AND T0已经过期。这只会选择列表在最后一批之前过期(即他们收到过期电子邮件)和超过 6 天前的人。
  3. 同样的逻辑适用 - 我们想知道他们收到了第二封电子邮件。SELECT car_id FROM cars WHERE Expiry_Date BETWEEN DATE_SUB(T1, INTERVAL 7 DAY) AND DATE_SUB(T0, INTERVAL 6 DAY)

我还建议您不要永久删除列表,而是将它们复制到 DeletedListings 表或使用 Deleted 列标记它们 - 每个都有其优点和缺点。在信息时代,永远不要丢弃数据——你永远不知道它什么时候有价值。

于 2013-02-04T06:16:23.137 回答