查询中的MySQL时间间隔

3
我希望能通过我的网站运行一个cron任务,该任务将获取所有未活跃超过两个月零一天的电子邮件地址。
我看到了这篇文章: 如何使用MySQL从新闻表中选择最近6个月 因此我知道我想要做类似于以下的事情:
SELECT DISTINCT email FROM orders WHERE date = DATE_SUB(now(), INTERVAL 2 MONTH)

额外的一天让我有些困惑 - 我是否需要像这样指定一定数量的天数:
SELECT DISTINCT email FROM orders WHERE date = DATE_SUB(now(), INTERVAL 63 DAYS)

但是我担心有不同天数的月份(29、30、31天),所以是否需要编写一个小脚本,在设置间隔之前检查该月的天数?

可能我把这个问题想复杂了,所以任何帮助都将不胜感激!

谢谢

1个回答

5
你只能同时使用一种类型与INTERVAL。有几种“混合”类型,如HOUR_SECONDYEAR_MONTH,但似乎没有可用于j个月和k天间隔的MONTH_DAY混合类型。

话虽如此,DATE_ADDDATE_SUB函数存在使简单的日期算术更易读。你仍然可以使用日期算术的基本形式,但不够易读—看看运行以下查询时会发生什么:

CREATE TEMPORARY TABLE foo (SELECT NOW() a, NOW()+1 b, NOW()+10000000000001 c);

SELECT * FROM foo;

DESCRIBE foo;

请不要在尝试运行第三个查询之前对第二个查询进行太长时间的盯视。这里发生的情况是MySQL可以用几种方式表示DATETIME,包括字符串形式:'YYYY-MM-DD hh:mm:ss'或等价地,作为双精度数值:YYYYMMDDhhmmss.ffffff,其中f表示秒的小数部分,保留六位(微秒分辨率)。
了解上述内容后,一个天真的解决方案可能是:
SELECT NOW() - 00000201000000.000000
             # YYYYMMDDhhmmss.ffffff   (format of above)

但是,即使你在表示日期时间,你仍然在使用数字,所以你不需要所有那些额外的前导零或空的小数位。你可以使用以下方式替代:

SELECT NOW() - 201000000
             # MDDhhmmss   (format of above)

最后,您可以将此数字结果 CASTDATETIME 格式以在查询中使用:

SELECT DISTINCT email FROM orders WHERE date = CAST(NOW() - 201000000 AS DATETIME)

有数十种其他方法可以做到这一点。为了易读性,我的首选可能是以下方法:
SELECT DISTINCT email FROM orders WHERE date = ((NOW() - INTERVAL 2 MONTH) - INTERVAL 1 DAY)

算术表达式中的分组不是必需的,但我建议至少使用外部一组括号来强调两个减法都是有意义的。个人认为,如果我看到 "NOW() - INTERVAL 2 MONTH - INTERVAL 1 DAY",我可能会想知道是否有人打算从一个间隔更改到另一个间隔,只是忘记删除一些代码。但这是您的样式选择(无论如何,注释您的代码是最明确的方式)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接