Сравнение 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.