查询的MySQL时间间隔

hlh*_*406 3 mysql date intervals

我想通过我的网站执行Cron工作,该工作将提取2个月零1天以来未激活的所有电子邮件地址。

我看过这篇文章:

如何使用MySQL从新闻表中选择最近6个月

所以我知道我想做这样的事情:

SELECT DISTINCT email FROM orders WHERE date = DATE_SUB(now(), INTERVAL 2 MONTH)
Run Code Online (Sandbox Code Playgroud)

额外的一天让我有些困惑-我是否必须指定这样的天数:

SELECT DISTINCT email FROM orders WHERE date = DATE_SUB(now(), INTERVAL 63 DAYS)
Run Code Online (Sandbox Code Playgroud)

但是然后我担心它们中的长度不同的月份(29、30、31),是否也需要编写一个小的脚本来检查设置间隔之前月份中的天数呢?

可能我将其弄得太复杂了,因此不胜感激!

谢谢

Air*_*Air 5

您一次只能使用一种类型INTERVAL。有几种“混合”,例如HOUR_SECOND或,YEAR_MONTH但似乎没有MONTH_DAY可用的混合类型,这种混合使用的时间间隔为j几个月和k几天。

就是说,DATE_ADDDATE_SUB函数的存在使简单的日期算术更具可读性。您仍然可以以更基本,更易读的形式使用日期算术-查看运行以下查询时发生的情况:

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

SELECT * FROM foo;

DESCRIBE foo;
Run Code Online (Sandbox Code Playgroud)

在尝试运行第三个查询之前,不要在第二个查询上斜视太长时间。这里发生的是,MySQL可以DATETIME通过几种方式表示a ,包括表示为字符串:'YYYY-MM-DD hh:mm:ss'或等效地表示为双精度数值:YYYYMMDDhhmmss.ffffff其中,f表示小数点后一位至六位(微秒分辨率)。

理解以上内容,天真的解决方案可能是:

SELECT NOW() - 00000201000000.000000
             # YYYYMMDDhhmmss.ffffff   (format of above)
Run Code Online (Sandbox Code Playgroud)

但是,即使您代表的是日期时间,您仍在使用数字,因此您不需要所有这些额外的前导零或空的小数位。您可以改为:

SELECT NOW() - 201000000
             # MDDhhmmss   (format of above)
Run Code Online (Sandbox Code Playgroud)

最后,您可以CAST将此数值结果转换回DATETIME查询中使用的格式:

SELECT DISTINCT email FROM orders WHERE date = CAST(NOW() - 201000000 AS DATETIME)
Run Code Online (Sandbox Code Playgroud)

还有许多其他方法可以做到这一点。为了便于阅读,我更喜欢以下内容:

SELECT DISTINCT email FROM orders WHERE date = ((NOW() - INTERVAL 2 MONTH) - INTERVAL 1 DAY)
Run Code Online (Sandbox Code Playgroud)

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