Porównanie daty i godziny SQLite


117

Wydaje się, że nie mogę uzyskać wiarygodnych wyników zapytania względem bazy danych sqlite przy użyciu ciągu daty i godziny jako porównania:

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

jak mam obsługiwać porównania datetime do sqlite?

update: field mydate jest typem danych DateTime


1
W jakim formacie daty jest przechowywana wartość w Twojej mydatekolumnie? Domyślam się, że nie jest to jeden z obsługiwanych formatów SQLite: sqlite.org/lang_datefunc.html
— Kucyki OMG

1
OMG, to typ danych z datą i godziną
— Brad

4
To użycie datetime () da w wyniku dokładną wartość, którą mu podałeś, nie ma powodu, aby go tutaj używać: po prostu użyj zamiast tego ciągu. A jeśli masz do czynienia tylko z datami, powinieneś usunąć zerowe części czasu - zasadniczo upewnij się, że obie strony są w tym samym formacie. (W przeciwnym razie '2009-11-13'dla mojej daty będzie mniej niż '2009-11-13 00:00:00'.)

1
Aby program Visual Studio z SQLite działał dla mnie i uruchamiał zapytanie o datę / godzinę, muszę użyć tego, Datetime()co @Brad zawarł w swojej wzmiance o rozwiązaniu. W przeciwnym razie VS2012 narzeka. Dziękuję Brad.
— CaptainBli

dziękuję za aktualizację rozwiązania. Jakie to dziwne, że domyślny format dat w .NET faktycznie spowoduje odwrotny skutek dla „<” vs ”>”.
— Dave Friedel

Odpowiedzi:


57

SQLite nie ma dedykowanych typów datetime , ale ma kilka funkcji datetime . Postępuj zgodnie z formatami reprezentacji ciągów (właściwie tylko formatami 1-10) rozumianymi przez te funkcje (przechowując wartość jako ciąg), a następnie możesz ich użyć, a także porównanie leksykograficzne na ciągach będzie pasowało do porównania dat i godzin (o ile nie spróbuj porównać daty z czasami lub daty z czasami, co i tak nie ma większego sensu).

W zależności od używanego języka możesz nawet uzyskać automatyczną konwersję . (Co nie dotyczy porównań w instrukcjach SQL, takich jak przykład, ale ułatwi Ci życie).


10
Dla wszystkich, którzy czytają pierwsze zdanie, w '17 SQLite ma dateidatetime
— alisianoi

3
Wczoraj czytałem o powinowactwie typów tutaj: sqlite.org/datatype3.html Zasadniczo, jeśli potrzebujesz daty, deklarujesz date(lub datetime) w kolumnie, która wewnętrznie jest traktowana jako text. To pasuje do moich potrzeb.
— alisianoi

100

Aby rozwiązać ten problem, przechowuję daty jako YYYYMMDD. A zatem, where mydate >= '20090101' and mydate <= '20050505'

Po prostu DZIAŁA cały czas. Konieczne może być tylko napisanie parsera do obsługi sposobu, w jaki użytkownicy mogą wprowadzać swoje daty, aby można było je przekonwertować na YYYYMMDD.


2
Zakładając, że format jest ustandaryzowany, czym różni się RRRR-MM-DD od braku myślników? Czy porównania nie skończyłyby się tak samo?
— Damon,

2
@Damon: myślę, że używa int dla typu danych
— thumbmunkeys

1
Nie, to są ciągi znaków - widać to w cudzysłowach - ale to jest świetny pomysł: przy tym zamówieniu RR MM DD można porównać daty. @Damon, to też powinno działać z myślnikami!
— Sedat Kilinc

1
Zastanawiam się, czy mogę zrobić to samo, jeśli użyję do przechowywania formatu rrrrMMddHHmmss, aby uwzględnić również część czasu. Czy spowodowałoby to przepełnienie, czy coś?
— faizal

2
Używam: yyyyMMddHHmm bez problemu, spodziewałbym się, że rrrrMMddHHmmss będzie działać tak samo
— Steve Byrne

39

Ostatnio miałem ten sam problem i rozwiązałem go w ten sposób:

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

% s musi być ujęty w pojedyncze cudzysłowy, np .: strftime ('% s', data)
— mvladic

To działa. Zmodyfikowane rozwiązanie polegające na zaznaczaniu wszystkich wierszy po określonej dacie: SELECT * FROM table WHERE strftime ('% s', added)> strftime ('% s', „2017-01-01 00:00:00”)
— Nowy programista

Oceniam użycie strftimew klauzuli WHERE, tak jak w tym przykładzie, i mam pytanie: czy użycie w strftimeten sposób jest wydajne ? Czy jest oceniany raz dla każdego wiersza czy raz na zapytanie?
— Alvaro Gutierrez Perez

należy to zaakceptować jako poprawną odpowiedź!
— Luka Sh

20

Poniższe działa dobrze dla mnie przy użyciu SQLite:

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

To zadziałało dla mnie w iOS, Objective-C Moje zapytanie wygląda następująco: WYBIERZ COUNT (carSold) FROM cars_sales_tbl GDZIE data MIĘDZY „2015-04-01” a „2015-04-30” AND carType = „Hybrid”
— Randika Vishman

9

Sqlite nie może porównywać dat. musimy zamienić na sekundy i rzucić na liczbę całkowitą.

Przykład

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

8

Następujące pracowały dla mnie.

SELECT *
FROM table_log
WHERE DATE(start_time) <= '2017-01-09' AND DATE(start_time) >= '2016-12-21'

zamiast tego możesz użyć między.
— Tamim Attafi

6

Mam sytuację, w której potrzebuję danych sprzed dwóch dni i do końca dnia dzisiejszego. Doszedłem do następującego.

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

Ok, technicznie jutro też ściągam o północy jak na oryginalnym plakacie, jeśli były jakieś dane, ale wszystkie moje dane są historyczne.

Kluczową rzeczą do zapamiętania był wstępny plakat wykluczający wszystkie dane po 2009-11-15 00:00:00. Tak więc wszystkie dane, które zostały zarejestrowane o północy piętnastego, zostały uwzględnione, ale żadne dane po północy piętnastego nie zostały uwzględnione. Jeśli ich pytanie brzmiało,

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

Dla jasności użyj klauzuli między.

Byłoby trochę lepiej. Nadal nie uwzględnia sekund przestępnych, w których godzina faktycznie może mieć więcej niż 60 sekund, ale wystarczająco dobrze do dyskusji tutaj :)


2

Musiałem przechowywać czas z informacją o strefie czasowej i byłem w stanie uzyskać zapytania działające w następującym formacie:

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

Czas jest przechowywany w bazie danych jako zwykły TEKST w następującym formacie:

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

2

Poniżej znajdują się metody porównywania dat, ale wcześniej musimy określić format daty przechowywanej w DB

Mam daty zapisane w formacie MM / DD / RRRR GG: MM, więc należy je porównać w tym formacie

  1. Poniższe zapytanie porównuje konwersję daty do formatu MM / DD / RRR i uzyskuje dane z ostatnich pięciu dni do dzisiaj. Operator BETWEEN pomoże i możesz po prostu określić datę rozpoczęcia ORAZ datę zakończenia.

    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. Poniższe zapytanie użyje operatora większe niż (>).

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

Wszystkie obliczenia, które wykonałem, wykorzystują aktualny czas, możesz zmienić format i datę zgodnie z potrzebami.

Mam nadzieję, że to ci pomoże

Summved


1

Możesz także napisać własne funkcje użytkownika do obsługi dat w wybranym formacie. SQLite ma dość prostą metodę pisania własnych funkcji użytkownika. Na przykład napisałem kilka, aby dodać razem okresy czasu.


0

Moje zapytanie wykonałem w następujący sposób:

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

Otrzymałem wskazówkę dzięki odpowiedzi @ ifredy. Wszystko, co zrobiłem, to to, że chciałem, aby to zapytanie było uruchamiane w systemie iOS przy użyciu Objective-C. I to działa!

Mam nadzieję, że ktoś, kto zajmuje się programowaniem na iOS, również skorzysta z tej odpowiedzi!


0

Obecnie zajmuję się tworzeniem przy użyciu pakietu System.Data.SQlite NuGet (wersja 1.0.109.2). Które używają SQLite w wersji 3.24.0.

I to działa dla mnie.

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

Nie używam funkcji datetime (). Być może zaktualizowali już zapytanie SQL w tej wersji SQLite.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.