您好我的mysql查询中的日期逻辑完全混淆了每天上午12:00运行的cron作业
我正在开设一个汽车列表网站,其中汽车列表的日期为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完全按照我的意愿完成工作。还请告诉我它在哪里&gt; =(大于或等于)或&lt; =(小于或等于)
这是sqlfiddle表结构和几个记录(虽然它们尚未过期)
http://sqlfiddle.com/#!2/cfcdf
我真的很感激帮助。
答案 0 :(得分: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;
开放他们正在根据您的需要工作。
答案 1 :(得分:1)
这是你在找什么?请尝试添加其他列,以查看expiry_date
和current date time
之间的差异,以便更好地了解您要处理的日期。 Please look into some dates functions in MYSQL.
-- 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
;
答案 2 :(得分:0)
您的查询没有什么明显的错误,如果您不了解您使用的功能,那么请谷歌查看它们,直到您阅读它们为止。
您的方法存在一个根本问题,即它依赖于完全 24小时间隔运行的cron作业 - 达到毫秒级 - 或者会出现双重上升和/或遗漏。< / p>
您需要另一个表来存储批处理程序上次运行的详细信息;使用1行进行初始化,过去很长一段时间,以便我们有一个起点。
您可以按SELECT MAX(date_ran) FROM BatchRecordTables
获取最新批次。将其存储在局部变量T0中。获取当前时间,将其存储在本地变量T1中(不要在多个查询中使用NOW(),因为它们将是稍微不同的时间,并且您需要它们相同)。我不知道这个的语法是MySQL - 你必须查找它。
然后你的情况就变成了。
SELECT car_id FROM cars WHERE Expiry_Date BETWEEN T0 AND T1
。这将仅选择此批次与前一批次之间已过期的人员。SELECT car_id FROM cars WHERE Expiry_Date BETWEEN DATE_SUB(T1, INTERVAL 6 DAY) AND T0
。这只会选择那些列表在最后一批之前过期的人(即他们收到了已发送的电子邮件)以及超过6天前的人。SELECT car_id FROM cars WHERE Expiry_Date BETWEEN DATE_SUB(T1, INTERVAL 7 DAY) AND DATE_SUB(T0, INTERVAL 6 DAY)
我还建议您不要永久删除列表,但要么将它们复制到DeletedListings表,要么将它们标记为Deleted列 - 每个列表都有自己的优点和缺点。在信息时代,永远不要丢弃数据 - 你永远不知道什么时候它可能是有价值的。