Как получить ближайшую дату времени в базе данных в sqlite - PullRequest
0 голосов
/ 06 сентября 2018

Время хранения базы данных и подобное значение.

    datetimes            val
2018-09-04 11:02:15     0.24
2018-09-04 11:55:24     0.29
2018-09-04 12:01:15     0.31
2018-09-04 12:40:55     0.40
2018-09-04 13:45:23     0.49
2018-09-04 13:55:26     0.51
2018-09-04 14:20:58     0.65

Я хочу получить val и datetime ближайшего времени в часе.

Пример datetimes = 2018-09-04 11:02:15 ближе всего к 11:00:00, поэтому я получаю (2018-09-04 11:02:15, 0.24)

Я знаю, как приблизиться.

SELECT *
FROM ValueRecord
ORDER BY abs(strftime('%s','2018-09-04 13:00:00') - strftime('%s', datetimes))
LIMIT 1;

но возвращается только одна запись.

Я хочу получить все записи, соответствующие условию

Это, вероятно, тот результат, который мне нужен в данных примера

    datetimes            val
2018-09-04 11:02:15     0.24   // nearest 11:00:00
2018-09-04 12:01:15     0.31   // nearest 12:00:00
2018-09-04 12:40:55     0.40   // nearest 13:00:00
2018-09-04 13:55:26     0.51   // nearest 14:00:00

Можно ли использовать SQL в SQLite? Если так, как я могу это сделать?

Или я должен сделать это с внешним кодом?

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Вот что я придумал:

SELECT *
FROM ValueRecord AS VR1
WHERE NOT EXISTS (
  SELECT 1 
  FROM ValueRecord AS VR2
  WHERE (
       ( CAST(strftime('%H', VR1.datetimes) AS INTEGER) = CAST(strftime('%H', VR2.datetimes) AS INTEGER)
     AND CAST(strftime('%M', VR1.datetimes) AS INTEGER) < 30 
     AND CAST(strftime('%M', VR2.datetimes) AS INTEGER) < 30 )
  OR 
       ( CAST(strftime('%H', VR1.datetimes) AS INTEGER) = CAST(strftime('%H', VR2.datetimes) AS INTEGER) - 1
     AND CAST(strftime('%M', VR1.datetimes) AS INTEGER) > 29 
     AND CAST(strftime('%M', VR2.datetimes) AS INTEGER) < 30 )
  OR   
       ( CAST(strftime('%H', VR1.datetimes) AS INTEGER) = CAST(strftime('%H', VR2.datetimes) AS INTEGER) + 1
     AND CAST(strftime('%M', VR2.datetimes) AS INTEGER) > 29 
     AND CAST(strftime('%M', VR1.datetimes) AS INTEGER) < 30 ) 
        )
  AND ABS(CASE WHEN CAST(strftime('%M', VR2.datetimes) AS INTEGER) > 29 THEN 3600 ELSE 0 END -
         (CAST(strftime('%M', VR2.datetimes) AS INTEGER) * 60 + CAST(strftime('%S', VR2.datetimes) AS INTEGER)))
      <
      ABS(CASE WHEN CAST(strftime('%M', VR1.datetimes) AS INTEGER) > 29 THEN 3600 ELSE 0 END -
         (CAST(strftime('%M', VR1.datetimes) AS INTEGER) * 60 + CAST(strftime('%S', VR1.datetimes) AS INTEGER))) 
  ) 
ORDER BY datetimes
LIMIT 10;

Обратите внимание, что результаты:

datetimes           val
2018-09-04 11:02:15 0.24
2018-09-04 12:01:15 0.31
2018-09-04 12:40:55 0.4
2018-09-04 13:45:23 0.49
2018-09-04 13:55:26 0.51

Отличаются от ваших, поскольку включают строки, которые считаются ближайшими к следующему часу.

Работаем в скрипке здесь: http://sqlfiddle.com/#!5/11522/42/0

0 голосов
/ 06 сентября 2018
select 
date_time,
case when substr(strftime('%H.%M',date_time),4,5) <='30' then strftime('%H',date_time)
else strftime('%H',date_time)+1
end closest_hour,
value
from sample;

Я установил 30 как значение пола и потолка. Измените его согласно вашему требованию ссылка sqlfiddle: Пример

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...