我正在尝试为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天前选择它返回零行的原因。
所以请稍微尊重,因为我是白痴的主人迪翁。
答案 0 :(得分:1)
在我看来,您希望选择date_updated
值位于一段时间内的行。例如,我认为您的意思是,如果NOW()
为2017-04-03 17:55:22
,您希望所有记录在2017-04-03 14:00:00
和2017-04-03 14:59:50.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)
请注意时间范围结束时的<
,而不是<=
。
这里发生了一些时区事情。 Unix时间戳(或应该)始终相对于UTC记录。 UNIX_TIMESTAMP()
函数始终从本地时间转换为UTC,NOW()
函数始终在本地时间运行,因此这一切都应该正常工作。但是如果你仍然得到错误的行或没有行,你可能会调查所有这些时间戳垃圾。
请注意,如果您的专栏具有TIMESTAMP
数据类型而不是INT
数据类型,那么您的时间精确度将会相同,并且您的生活会更轻松。
答案 1 :(得分:0)
你可以使用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)