2015-06-24 2 views
0

Я пытаюсь написать инструкцию SQLite, чтобы получить ближайшее время datetime от пользовательского ввода (из WPF datepicker). У меня есть таблица IRquote (rateId, quoteDateAndTime, quoteValue).SQLite-запрос, чтобы получить ближайшее datetime

Например, если пользователь вводит 10/01/2000, а база данных хранит только фиксацию для 08/01/2000, 07/01/2000 и 14/01/2000, она вернется 08/01/2000 , являясь самой близкой датой от 10/01/2000.

Конечно, я бы хотел, чтобы он работал не только с датами, но и со временем.

Я пытался с этим запросом, но он возвращает строку с датой дальней, а не самым близким:

SELECT quoteValue FROM IRquote 
WHERE rateId = '" + pRefIndexTicker + "' 
ORDER BY abs(datetime(quoteDateAndTime) - datetime('" + DateTimeSQLite(pFixingDate) + "')) ASC 
LIMIT 1; 

Обратите внимание, что у меня есть функция DateTimeSQLite для преобразования пользовательского ввода в нужном формат.

Я не понимаю, почему это не работает. Как я мог это сделать? Спасибо за вашу помощь.

+1

Откуда вы получаете этот вход пользователя? Где хранятся данные? –

+1

Я не уверен во всех командах SQL, чтобы сделать это, но я подозреваю, что должен быть какой-то способ разграничить ввод с сохраненными значениями, получить из него числовое значение, сортировать по этому значению ('ORDER BY') , и возьмите первую запись ('TOP 1'). (Необязательно преобразовать в абсолютное значение перед сортировкой, если вы хотите получить самое близкое время в любом направлении.) – David

+0

@BerndLinde Я отредактировал мой вопрос, чтобы добавить более подробную информацию. Дэвид Я попробую еще раз с предложенным методом. Спасибо за вашу помощь – MarinD

ответ

4

Чтобы получить ближайшую дату, вам необходимо использовать функцию SQLite strftime('%s', datetime).

С примером this примера/демо вы получите самую близкую дату к указанной дате.
Обратите внимание, что дата 2015-06-25 10:00:00 - это дата и время ввода, выбранные пользователем.

select t.ID, t.Price, t.PriceDate, 
     abs(strftime('%s','2015-06-25 10:00:00') - strftime('%s', t.PriceDate)) as 'ClosestDate' 
    from Test t 
order by abs(strftime('%s','2015-06-25 10:00:00') - strftime('%s', PriceDate)) 
limit 1; 

SQL Объяснение:
Мы используем strftime('%s') - strftime('%s') вычислить разницу в секундах между двумя датами (Примечание: он должен быть '% s', а не '% S'). Поскольку это может быть как положительным, так и отрицательным, нам также необходимо использовать функцию abs, чтобы сделать все это положительным, чтобы убедиться, что наши order by и последующие разделы limit 1 работают правильно.

+0

Очень неэффективно, конвертируя даты в строки. –

+0

@ypercube SQLite хранит DateTime как строку, поэтому никакого преобразования на самом деле не происходит. В SQLite нет типа DateTime –

+0

Я добавил ответ с запросом, который может использовать индекс для столбца (и thnx для скрипта, я тоже использовал его) –

2

Если таблица большая, и есть индекс на столбце даты и времени, это будет использовать индекс, чтобы получить 2 ближайших строк (выше и ниже прилагаемого значения) и будет более эффективным:

select * 
from 
    (select * 
    from 
    (select t.ID, t.Price, t.PriceDate 
     from Test t 
     where t.PriceDate <= datetime('2015-06-23 10:00:00') 
     order by t.PriceDate desc 
     limit 1 
    ) d 
    union all 
    select * from 
    (select t.ID, t.Price, t.PriceDate 
     from Test t 
     where t.PriceDate > datetime('2015-06-23 10:00:00') 
     order by t.PriceDate asc 
     limit 1 
    ) a 
) x 
order by abs(julianday('2015-06-23 10:00:00') - julianday(PriceDate)) 
limit 1 ; 

Проведено SQLfiddle.

Смежные вопросы