Я пытаюсь найти значение datetime в базе данных 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 дней). В настоящее время он запускается для каждого отдельного datetime из другого массива, но я понимаю, что это не оптимально. Запрос динамически создается в PHP.
Время запроса в настоящее время составляет около 1,1 с за запрос, поэтому запуск 30 раз и более становится проблематичным, таблица содержит сотни тысяч строк.
Еще раз спасибо!
Основная идея заключается в использовании 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
Использовать ABS ()
SELECT one FROM table ORDER BY ABS(`datetimefield` - '2014-12-10 09:45:00') LIMIT 1
Это вернет строку с наименьшей разницей, ближайшей.
Использование 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;