Порівняння SQLite DateTime


117

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

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

як я маю поводитися зі співставленнями дат на час sqlite?

update: поле mydate - це тип даних DateTime


1
Який формат дати - це значення, збережене у вашому mydateстовпці? Я здогадуюсь, що це не один із форматів, що підтримуються SQLite: sqlite.org/lang_datefunc.html
OMG

1
OMG, це тип даних дата
Бред

4
Якщо використання datetime () призведе до точного значення, яке ви йому надали, тут немає ніяких причин використовувати його: просто використовуйте рядок замість цього. І якщо ви маєте справу лише з датами, вам слід видалити нульові часові частини --- по суті переконайтесь, що обидві сторони мають однаковий формат. (Інакше '2009-11-13'для моїх дат буде менше '2009-11-13 00:00:00'.)

1
Для того, щоб Visual Studio з SQLite працював на мене для запуску запиту на дату / час, мені потрібно використовувати так Datetime()само, як @Brad включив у свою згадку про рішення. Інакше VS2012 скаржиться. Дякую Бред.
КапітанБлі

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

Відповіді:


57

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

Залежно від того, якою мовою ви користуєтесь, ви навіть можете отримати автоматичне перетворення . (Що не стосується порівнянь у SQL-операторах, як приклад, але полегшить ваше життя.)


10
Для всіх, хто читає перше речення, "17 серпня SQLite має dateіdatetime
17:29

3
Вчора читав про спорідненість типу тут: sqlite.org/datatype3.html В основному, якщо вам потрібна дата, ви оголошуєте date(або datetime) у стовпці, який внутрішньо трактується як text. Це відповідає моїм потребам.
alisianoi

100

Щоб вирішити цю проблему, я зберігаю дати як YYYYMMDD. Таким чином, where mydate >= '20090101' and mydate <= '20050505'

Це просто звичайно РОБОТИ весь час. Вам може знадобитися лише написати аналізатор, щоб вирішити, як користувачі можуть вводити свої дати, щоб ви могли їх перетворити YYYYMMDD.


2
За умови стандартизації формату, чим би YYYY-MM-DD відрізнявся від без тире? Хіба порівняння не закінчилися б однаковими?
Деймон

2
@Damon: я думаю, він використовує int для типу даних
thumbmunkeys

1
Ні, це рядки - ви можете побачити це в котируваннях - Але це чудова ідея: з таким замовленням YY MM DD можна порівняти дати. @Damon він також повинен працювати з тире!
Sedat Kilinc

1
Мені цікаво, чи можу я зробити те ж саме, якщо для зберігання використовую формат yyyyMMddHHmmss, щоб я міг також включати частину часу. Це спричинило б перелив чи щось таке?
Faizal

2
Я використовую: yyyyMMddHHmm без жодних проблем, я б очікував, що yyyyMMddHHmmss працюватиме так само
Steve Byrne

39

У мене було те саме питання нещодавно, і я вирішив його так:

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

% s має бути укладено між символами однієї цитати, тобто: strWeather ('% s', дата)
mvladic

Це працює. Модифіковане рішення для вибору всіх рядків після визначеної дати: ВИБІРТЬ * З таблиці, БОГО строк ('% s', додано)> строку ('% s', "2017-01-01 00:00:00")
Новий Прогмер

Я оцінюю використання strftimeв пункті WHERE, як у цьому прикладі, і у мене виникає питання: чи ефективно використовувати strftimeтаке? Чи оцінюється вона один раз для кожного рядка чи один раз за запитом?
Альваро Гутьеррес Перрес

це слід сприймати як правильну відповідь!
Лука Ш

20

Наступне працює добре для мене за допомогою SQLite:

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

Це працювало для мене в iOS, Objective-C Мій запит виглядає наступним чином: ВИБІРУЙТЕ КОЛІКУ (продано) ВІД автомобілів_sales_tbl, КОГО дата МІЖ "2015-04-01" І "2015-04-30" І carType = "Гібрид"
Рандіка Вішман

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') 

Гаразд, технічно я також залучаю завтра опівночі, як оригінальний плакат, якщо були якісь дані, але мої дані всі історичні.

Головне, що слід пам’ятати, початковий плакат виключав усі дані після 2009-11-15 00:00:00. Отже, будь-які дані, зафіксовані опівночі 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')"

Час зберігається в базі даних як звичайний TEXT у такому форматі:

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

2

Нижче наведено методи порівняння дат, але перед цим нам потрібно визначити формат дати, що зберігається в БД

У мене дати зберігаються у форматі MM / DD / YYYY HH: MM, тому його потрібно порівнювати у такому форматі

  1. Нижче запит порівнює дату перетворення у формат MM / DD / YYY та отримує дані за останні п’ять днів до сьогодні. МЕРЕЖ оператор допоможе, і ви можете просто вказати дату початку та дату закінчення.

    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');  

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

Сподіваюся, що це вам допоможе

Підведено підсумки


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

Зараз я розвиваюсь за допомогою пакету System.Data.SQlite NuGet (версія 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.