3

我想通过我的网站运行一项 cron 作业,它将获取所有 2 个月零 1 天以来未激活的电子邮件地址。

我看过这个帖子:

如何使用 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),那么在设置间隔之前是否也必须编写一个小脚本来检查该月的天数?

可能我把它弄得太复杂了,所以任何帮助都将不胜感激!

谢谢

4

1 回答 1

5

一次只能使用一种类型INTERVAL。有几个像HOUR_SECONDor这样的“混合”,YEAR_MONTH但似乎没有任何MONTH_DAY混合类型可以用于j几个月和k几天的间隔。

话虽如此,DATE_ADDandDATE_SUB函数的存在是为了使简单的日期算术更具可读性。您仍然可以以更基本但可读性较差的形式使用日期算术 - 看看运行以下查询时会发生什么:

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

SELECT * FROM foo;

DESCRIBE foo;

在尝试运行第三个查询之前,不要对第二个查询眯眼太久。这里发生的是 MySQL 可以DATETIME用几种方式表示 a,包括作为字符串:'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)

最后,您可以CAST将此数值结果恢复为DATETIME用于查询的格式:

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我可能想知道是否有人打算从一个间隔更改为另一个,只是忘记删除一些代码。但是风格选择是你的(最明确的就是注释你的代码)。

于 2013-08-19T17:16:26.213 回答