【问题标题】:Select where unix timestamp falls on specified hour or day选择 unix 时间戳在指定小时或天的位置
【发布时间】:2017-04-03 22:16:42
【问题描述】:

我正在尝试为 MySQL 查询构建动态位置。用户可以选择他们想要多少小时或几天前的数据。我希望数据落在特定的几小时或几天前。

这是我现在正在使用但不起作用的代码:

$condition['dates'] = 'Specific';
$condition['date_operand'] = 'Hour(s) ago';
$condition['date_value'] = '3';

if ($conditions['dates'] == 'Specific' && !empty($conditions['date_value'])) {
    if ($conditions['date_operand'] == 'Hour(s) ago') {
        $where[] = "date_format(from_unixtime(l.date_updated), '%Y-%m-%d %H') = date_format(now() - interval ".$conditions['date_value']." hour, '%Y-%m-%d %H')";
    }
    else if ($conditions['date_operand'] == 'Day(s) ago') {
        $where[] = "date_format(from_unixtime(l.date_updated), '%Y-%m-%d') = date_format(now() - interval ".$conditions['date_value']." day, '%Y-%m-%d')";
    }
}

它似乎没有任何工作。 l.date_updated 是一个 unix 时间戳。您可以看到我正在努力实现的目标,但它不起作用。

更新

这里是示例中的 MySQL where 语句不起作用:

SELECT * FROM mytable l
WHERE DATE_FORMAT(FROM_UNIXTIME(l.date_updated), '%Y-%m-%d %H') = DATE_FORMAT(NOW() - INTERVAL 3 HOUR, '%Y-%m-%d %H')

它不会导致错误,只是没有选择我想要的。

最终更新

我的查询实际上很好。看来我的 PHP 代码正在连接到一个多年未更新的开发数据库。这就是为什么当我选择 3 天前它返回零行。

所以,请尊重一下,因为我是 Dion,白痴之王。

【问题讨论】:

  • 如果这是一个 mysql 问题,我建议删除 PHP 并仅包含您的查询。如果我们能真正看到查询,这将使我们更容易看到查询出了什么问题。
  • 我更新了 OP。
  • date_updated 列的 MySQL 数据类型是什么? TIMESTAMP? BIGINT? UNSIGNED INT?请edit您的问题以显示该信息。
  • @O.Jones 这是一个INT,包含一个unix时间戳。
  • 您是否检查了FROM_UNIXTIME(l.date_updated) 的返回以确保日期在您期望的时区?你说它不是在选择你想要的,而是它在选择什么?有什么事吗?

标签: mysql unix-timestamp


【解决方案1】:

在我看来,您想选择您的 date_updated 值位于某个时间范围内的行。例如,我认为您的意思是,如果 NOW() 是 2017-04-03 17:55:22,您希望所有记录的时间戳都在 2017-04-03 14:00:00 和 2017-04-03 14:59:59.99999 之间。

以下是您以 sargable 方式执行此操作的方法:一种可以在您的 date_updated 列上使用索引的方式。

此表达式将NOW() 截断到整点:17:55 到 17:00:

 DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00')

这会备份三个小时。

 DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00') - INTERVAL 3 HOUR

您的时间戳范围的开始是:

 UNIX_TIMESTAMP(DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00') - INTERVAL 3 HOUR)

那么,您的时间戳范围的结尾是

 UNIX_TIMESTAMP(DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00') - INTERVAL 2 HOUR)

所以,这个WHERE 子句可以解决问题。

 WHERE l.date_updated >= UNIX_TIMESTAMP(DATE_FORMAT(NOW(),'%Y-%m-%d %H:00:00')-INTERVAL 3 HOUR)
   AND l.date_updated) < UNIX_TIMESTAMP(DATE_FORMAT(NOW(),'%Y-%m-%d %H:00:00')-INTERVAL 2 HOUR)

注意时间范围末尾的&lt;,而不是&lt;=。

这里发生了一些时区问题。 Unix 时间戳总是(或应该)相对于 UTC 记录。 UNIX_TIMESTAMP() 函数总是从本地时间转换为 UTC,而 NOW() 函数总是在本地时间工作,所以这一切都应该正常工作。但是,如果您仍然得到错误的行或没有行,您可能会调查所有这些时间戳垃圾。

请注意,如果您的列具有 TIMESTAMP 数据类型而不是 INT 数据类型,那么您的时间精度将保持不变,并且您的生活会更轻松。

【讨论】:

  • 感谢您的回答。不过,我仍然不明白为什么我的原始查询不起作用。
【解决方案2】:

您可以使用 TO_SECONDS: https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_to-seconds

... where TO_SECONDS(l.date_updated) >= TO_SECONDS(NOW()-INTERVAL 3 HOUR)

【讨论】:

  • 再次,我希望它在同一时间选择项目。因此,如果有人选择 3 小时前,它应该抓取该小时 3 小时前的数据。秒和分钟无关紧要。
  • 好吧,那么您可能应该从您的数据库中提供一些示例数据
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-18
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
  • 2011-05-27
相关资源
最近更新 更多