我试图在mysql数据库中找到一个与我指定的日期时间最接近的日期时间值,我遇到了一些麻烦。
以下伪代码是我想要实现的:
SELECT one FROM table WHERE datetimefield is closest to "2014-12-10 09:45:00" LIMIT 1
提前致谢
修改
感谢到目前为止的回复,因为事实证明查询比我最初想到的要复杂得多,所以ABS方法可以很好地添加一些。
接下来的问题是,无论如何都要降低对以下查询的性能要求吗?
SELECT DISTINCT timegenerated, *other values*
FROM table1 e INNER JOIN table2 dt
ON e.circuit = dt.circuit
WHERE dt.circuit IN ("2", "3", "4", "5", "6", "7", "8")
AND e.circuit != 1
AND dt.siteid = 435
ORDER BY ABS(TIMESTAMPDIFF(MINUTE, timegenerated, "2014-12-09 14:15:00")) LIMIT 7
或者将其合并以匹配多个日期,因为我需要能够匹配多个特定日期时间(可能多达90天)它当前正在从另一个阵列运行每个单独的日期时间但我意识到这不是最佳的。该查询是在PHP中动态构建的。
查询时间目前约为每个查询1.1秒,因此运行30次或更多时间会产生问题,该表有数十万行。
再次感谢!
答案 0 :(得分:29)
关键的想法是使用order by
和limit
:
如果你想要最近的那个:
SELECT one
FROM table
WHERE datetimefield <= '2014-12-10 09:45:00'
ORDER BY datetimefield DESC
LIMIT 1;
如果您想要最接近的方向,请使用TIMESTAMPDIFF()
:
ORDER BY abs(TIMESTAMPDIFF(second, datetimefield, '2014-12-10 09:45:00'))
LIMIT 1
答案 1 :(得分:4)
使用ABS()
SELECT one FROM table
ORDER BY ABS(`datetimefield` - '2014-12-10 09:45:00') LIMIT 1
这将返回差异最小的行,即最接近的行。
答案 2 :(得分:3)
使用abs()可以防止使用datetimefield索引。我建议有一个选择最近的前一个和一个选择最近的后,使用索引,然后选择最接近的后:
create table `table` (datetimefield datetime key, one varchar(99));
insert into `table` values
('2014-06-01', 'a'), ('2014-12-01', 'b'),
('2015-01-01', 'c'), ('2015-02-01', 'd');
set @d = '2014-12-10 09:45:00';
select * from
(
( select *, TIMESTAMPDIFF(SECOND, @d, datetimefield) as diff
from `table` where datetimefield >= @d
order by datetimefield asc limit 1
)
union
( select *, TIMESTAMPDIFF(SECOND, datetimefield, @d) as diff
from `table` where datetimefield < @d
order by datetimefield desc limit 1
)
) x
order by diff
limit 1;