hlh*_*406 3 mysql date intervals
我想通过我的网站执行Cron工作,该工作将提取2个月零1天以来未激活的所有电子邮件地址。
我看过这篇文章:
所以我知道我想做这样的事情:
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),是否也需要编写一个小的脚本来检查设置间隔之前月份中的天数呢?
可能我将其弄得太复杂了,因此不胜感激!
谢谢
您一次只能使用一种类型INTERVAL
。有几种“混合”,例如HOUR_SECOND
或,YEAR_MONTH
但似乎没有MONTH_DAY
可用的混合类型,这种混合使用的时间间隔为j
几个月和k
几天。
就是说,DATE_ADD
和DATE_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
我可能会想知道是否有人打算从一个间隔更改为另一个间隔,而只是忘记删除一些代码。但是样式的选择是您自己的(最明确的是无论如何都要注释您的代码)。