Сравнение SQLite DateTime


118

Кажется, я не могу получить надежные результаты от запроса к базе данных sqlite, используя строку datetime в качестве сравнения следующим образом:

select * 
  from table_1 
 where mydate >= '1/1/2009' and mydate <= '5/5/2009'

как мне обрабатывать сравнение datetime с sqlite?

обновление: поле mydate - это тип данных DateTime


1
В каком формате даты значение хранится в вашем mydateстолбце? Я предполагаю, что это не один из поддерживаемых SQLite форматов: sqlite.org/lang_datefunc.html
OMG Ponies

1
OMG, это тип данных datetime
Брэд,

4
Это использование datetime () приведет к получению точного значения, которое вы ему дали, нет причин использовать его здесь: просто используйте вместо этого строку. И если вы имеете дело только с датами, вам следует удалить части с нулевым временем - по сути, убедитесь, что обе стороны находятся в одном формате. (В противном случае '2009-11-13'для mydate будет меньше чем '2009-11-13 00:00:00'.)

1
Чтобы Visual Studio с SQLite работал на меня, чтобы запустить запрос даты / времени, мне нужно использовать то Datetime()же самое, что @Brad включил в свое упоминание решения. В противном случае VS2012 жалуется. Спасибо, Брэд.
CaptainBli

спасибо, что обновили решение. Как странно, что формат дат по умолчанию в .NET на самом деле приводит к противоположному результату для "<" vs ">".
Дэйв Фридель

Ответы:


58

SQLite не имеет выделенных типов datetime , но имеет несколько функций datetime . Следуйте форматам строкового представления (на самом деле только форматы 1-10), понятным этим функциям (сохраняя значение в виде строки), и затем вы можете их использовать, плюс лексикографическое сравнение строк будет соответствовать сравнению даты и времени (если вы этого не сделаете). попробуйте сравнить даты со временем или дату со временем, что в любом случае не имеет большого смысла).

В зависимости от того, какой язык вы используете, вы можете даже получить автоматическое преобразование . (Что не относится к сравнениям в операторах SQL, подобных примеру, но облегчит вашу жизнь.)


10
Для всех, кто читает первое предложение, в SQLite 17 года есть dateиdatetime
alisianoi

3
Вчера читал о сходстве типов здесь: sqlite.org/datatype3.html В принципе, если вам нужна дата, вы объявляете date(или datetime) в столбце, который внутренне обрабатывается как text. Это соответствует моим потребностям.
alisianoi

100

Чтобы решить эту проблему, я храню даты как YYYYMMDD. Таким образом, where mydate >= '20090101' and mydate <= '20050505'

Он просто РАБОТАЕТ все время. Вам может потребоваться только написать синтаксический анализатор, чтобы обрабатывать, как пользователи могут вводить свои даты, чтобы вы могли преобразовать их в YYYYMMDD.


2
Если формат стандартизирован, чем будет отличаться YYYY-MM-DD от без тире? Разве сравнения не останутся такими же?
Damon

2
@Damon: я думаю, он использует int для типа данных
thumbmunkeys

1
Нет, это строки - вы можете увидеть это в кавычках - но это отличная идея: с таким порядком ГГ ММ ДД можно сравнивать даты. @Damon он тоже должен работать с тире!
Sedat Kilinc

1
Интересно, могу ли я сделать то же самое, если я использую для хранения формат yyyyMMddHHmmss, чтобы я мог также включить временную часть. Это вызовет переполнение или что-то в этом роде?
faizal

2
Я использую: yyyyMMddHHmm без проблем, я бы ожидал, что yyyyMMddHHmmss будет работать так же
Стив Бирн

39

Недавно у меня была такая же проблема, и я решил ее так:

SELECT * FROM table WHERE 
    strftime('%s', date) BETWEEN strftime('%s', start_date) AND strftime('%s', end_date)

% s должен быть заключен между символами одинарных кавычек, например: strftime ('% s', date)
mvladic

Оно работает. Модифицированное решение для выбора всех строк после определенной даты: SELECT * FROM table WHERE strftime ('% s', added)> strftime ('% s', "2017-01-01 00:00:00")
New Progammer

Я оцениваю использование strftimeв предложении WHERE, как в этом примере, и у меня есть вопрос: эффективно ли это использовать strftime? Он оценивается один раз для каждой строки или один раз для запроса?
Alvaro Gutierrez Perez

это следует принять как правильный ответ!
Luka Sh

20

При использовании SQLite у меня отлично работает следующее:

SELECT * 
    FROM ingresosgastos 
    WHERE fecharegistro BETWEEN "2010-01-01" AND "2013-01-01"

Это сработало для меня в iOS, Objective-C. Мой запрос выглядит следующим образом: ВЫБРАТЬ СЧЕТ (carSold) FROM cars_sales_tbl ГДЕ дата МЕЖДУ '2015-04-01' И '2015-04-30' И carType = "Hybrid"
Рандика Вишман

9

Sqlite не может сравнивать по датам. нам нужно преобразовать в секунды и привести его как целое число.

пример

SELECT * FROM Table  
WHERE  
CAST(strftime('%s', date_field)  AS  integer) <=CAST(strftime('%s', '2015-01-01')  AS  integer) ;


6

У меня есть ситуация, когда мне нужны данные за два дня назад и до конца сегодняшнего дня. Я пришел к следующему.

WHERE dateTimeRecorded between date('now', 'start of day','-2 days') 
                           and date('now', 'start of day', '+1 day') 

Хорошо, технически я также прибегаю к полуночи завтра, как исходный плакат, если были какие-то данные, но все мои данные исторические.

Главное, что нужно помнить, из первоначального плаката были исключены все данные после 00:00:00 15.11.2009. Таким образом, любые данные, записанные в полночь 15-го числа, были включены, но данные после полуночи 15-го числа не были включены . Если их запрос был,

select * 
  from table_1 
  where mydate between Datetime('2009-11-13 00:00:00') 
                   and Datetime('2009-11-15 23:59:59')

Использование предложения между для ясности.

Было бы немного лучше. Он по-прежнему не учитывает високосные секунды, в которых в часе может быть больше 60 секунд, но этого достаточно для обсуждения здесь :)


2

Мне пришлось хранить время с информацией о часовом поясе, и я смог получить запросы, работающие в следующем формате:

"SELECT * FROM events WHERE datetime(date_added) BETWEEN 
      datetime('2015-03-06 20:11:00 -04:00') AND datetime('2015-03-06 20:13:00 -04:00')"

Время хранится в базе данных как обычный ТЕКСТ в следующем формате:

2015-03-06 20:12:15 -04:00

2

Ниже приведены методы сравнения дат, но перед этим нам нужно определить формат даты, хранящейся в БД.

У меня есть даты, хранящиеся в формате ММ / ДД / ГГГГ ЧЧ: ММ, поэтому их нужно сравнивать в этом формате

  1. Ниже запрос сравнивает преобразованную дату в формат ММ / ДД / ГГГ и получает данные за последние пять дней до сегодняшнего дня. Оператор BETWEEN поможет, и вы можете просто указать дату начала И дату окончания.

    select * from myTable where myColumn BETWEEN strftime('%m/%d/%Y %H:%M', datetime('now','localtime'), '-5 day') AND strftime('%m/%d/%Y %H:%M',datetime('now','localtime')); 
  2. В запросе ниже будет использоваться оператор "больше" (>).

      select * from myTable where myColumn > strftime('%m/%d/%Y %H:%M', datetime('now','localtime'), '-5 day');  

Все вычисления, которые я сделал, используют текущее время, вы можете изменить формат и дату в соответствии с вашими потребностями.

Надеюсь, что это поможет вам

Summved


1

Вы также можете написать свои собственные пользовательские функции для обработки дат в выбранном вами формате. В SQLite есть довольно простой метод написания собственных пользовательских функций. Например, я написал несколько, чтобы сложить продолжительность.


0

Свой запрос я сделал следующим образом:

SELECT COUNT(carSold) 
FROM cars_sales_tbl
WHERE date
BETWEEN '2015-04-01' AND '2015-04-30'
AND carType = "Hybrid"

Я получил подсказку от ответа @ifredy. Все, что я сделал, это то, что я хотел, чтобы этот запрос выполнялся в iOS с использованием Objective-C. И это работает!

Надеюсь, что тот, кто занимается разработкой для iOS, тоже воспользуется этим ответом!


0

Прямо сейчас я разрабатываю с помощью пакета NuGet System.Data.SQlite (версия 1.0.109.2). Что с использованием SQLite версии 3.24.0.

И у меня это работает.

SELECT * FROM tables WHERE datetime 
BETWEEN '2018-10-01 00:00:00' AND '2018-10-10 23:59:59';

Я не собираюсь использовать функцию datetime (). Возможно, они уже обновили SQL-запрос в этой версии SQLite.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.