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.