1

我想我要解决这个问题了。我想用 PHP 提取数据库中不到一天的行。我正在使用 Laravel,但这不相关。这是我所拥有的:

if ($day == 'today') {
    $date = date('Y-m-d H:i:s');
} elseif ($day == 'yesterday') {
    $date = date('Y-m-d H:i:s', strtotime('yesterday'));
} else {
    ...
}

$sql = "SELECT * FROM all_forms_main_contact WHERE DATEDIFF(timestamp, '" . $date . "') <= 1";
$mc = DB::select($sql);
return json_encode($mc);

但是,这不会返回正确的结果。它的返回结果早于一天。

4

5 回答 5

4

这实际上取决于您如何定义“不到一天”。

MySQLDATEDIFF函数仅考虑日期时间值的日期部分,并返回整数天数差。下面的两个查询都会返回一个值1,代表“1天”,其中一个是相差8小时,另一个是相差46小时:

SELECT DATEDIFF('2013-01-15 07:00','2013-01-14 23:00') AS 8_hrs
SELECT DATEDIFF('2013-01-15 23:00','2013-01-14 01:00') AS 46_hrs

因此,完全有可能并且预期您的查询可能会返回“早于”24 小时的行。

hh:mi:ss作为参数提供给 DATEDIFF 函数的文字的时间部分将被忽略,时间戳值的时间部分将被忽略。仅提供该YYYY-MM-DD值将获得相同的结果。)


另请注意,DATEDIFF 函数上的谓词是不可搜索的,也就是说,MySQL 无法对索引进行范围扫描以满足该谓词。

为了获得最佳性能,我们通常更喜欢裸列上的等效谓词,例如

WHERE `timestamp` >= expr

这使优化器至少可以考虑对timestamp列上的索引使用范围扫描。

如果您正在寻找不到 1 天的行(意味着不到 24 小时或不到 86400 秒),分辨率高达一秒,您可以使用如下谓词之一:

WHERE `timestamp` >= '2013-01-15 16:10' + INTERVAL -1 DAY
WHERE `timestamp` >= '2013-01-15 16:10' + INTERVAL -24 HOUR
WHERE `timestamp` >= '2013-01-15 16:10' + INTERVAL -86400 SECOND

DATE_ADD 函数是等效的:

WHERE `timestamp` >= DATE_ADD('2013-01-15 16:10',INTERVAL -1 DAY)

另请注意,不必在 SQL 文本中将当前日期值作为文字传递;MySQL 提供了从 MySQL 服务器返回当前日期和时间的内置函数,例如NOW(),CURRENT_DATE()SYSDATE().

对于分别小于 24 小时或 48 小时的行:

WHERE `timestamp` >= DATE_ADD(NOW(),INTERVAL -1 DAY)
WHERE `timestamp` >= DATE_ADD(NOW(),INTERVAL -2 DAY)
于 2013-01-15T22:15:12.577 回答
1

此查询选择比 -24 小时新的行。
例如,如果是 04:00 AM,则返回所有行 >=昨天 04:00 AM:

SELECT * FROM `tbl` WHERE `datetime` >= NOW() - INTERVAL 1 DAY

同样适用于 -48 小时以上。
例如,如果它是 04:00 AM,则返回所有行 >= 前天 04:00 AM:

SELECT * FROM `tbl` WHERE `datetime` >= NOW() - INTERVAL 2 DAY

此查询选择今天的行。
例如,如果是 04:00 AM,则返回所有行 >= 今天 00:00 AM:

SELECT * FROM `tbl` WHERE `datetime` >= CURDATE()

同样,此查询仅选择昨天的行。
例如,如果是 04:00 AM,则返回昨天 00:00 AM 到(但不包括)今天 00:00 AM 之间的所有行:

SELECT * FROM `tbl` WHERE `datetime` >= CURDATE() - INTERVAL 1 DAY AND `datetime` < CURDATE()

我将上述语法用于日期查询,我认为它比日期添加/子函数更具可读性。

于 2013-01-15T22:02:30.587 回答
0

您通常会像这样简单地对其进行编码:

...
where timestamp > subdate(now(), 1)

请注意,它的便捷版本subdate()允许将天数指定为简单整数(即默认间隔类型为DAY)。此外,如果第一个参数是 Daretine,则 subdate 返回日期时间。

于 2013-01-15T22:02:45.373 回答
0

为什么不这样做:

SELECT ... WHERE timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 1 DAY) AND NOW()
于 2013-01-15T21:58:46.553 回答
0

而 DATEDIFF 忽略时间组件(请参阅DATEDIFF - MariaDB Knowledge), TIMESTAMPDIFF 没有。所以这会起作用:

SELECT ... WHERE TIMESTAMPDIFF(DAY, NOW(), `timestamp`) = '0'

例如,如果 NOW() = '2020-01-02 00:00:01' 并且timestamp是 '2020-01-01 01:00:00',则上述代码将准确返回 0 天,但 DATEDIFF 将错误地返回 1 天(因为它忽略了时间分量。

于 2020-10-15T10:50:23.047 回答