SQLite DateTime-Vergleich

116

Ich kann anscheinend keine zuverlässigen Ergebnisse aus der Abfrage für eine SQLite-Datenbank erhalten, wenn ich eine datetime-Zeichenfolge als Vergleich verwende:

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

Wie soll ich mit Datetime-Vergleichen mit SQLite umgehen?

update: Feld mydate ist ein DateTime-Datentyp

Brad
quelle
1
Welches Datumsformat hat der in Ihrer mydateSpalte gespeicherte Wert ? Ich vermute, es ist nicht eines der von SQLite unterstützten Formate: sqlite.org/lang_datefunc.html
OMG Ponies
1
OMG, es ist ein Datetime-Datentyp
Brad
4
Diese Verwendung von datetime () führt zu dem genauen Wert, den Sie angegeben haben. Es gibt keinen Grund, ihn hier zu verwenden: Verwenden Sie stattdessen einfach die Zeichenfolge. Und wenn Sie nur mit Datumsangaben arbeiten, sollten Sie die Nullzeitteile löschen - stellen Sie im Wesentlichen sicher, dass beide Seiten das gleiche Format haben. (Andernfalls '2009-11-13'ist für mydate weniger als '2009-11-13 00:00:00'.)
1
Damit Visual Studio mit SQLite für mich eine Datums- / Datetime()Zeitabfrage ausführen kann, muss ich das verwenden, wie es @Brad in seiner Erwähnung der Lösung angegeben hat. Ansonsten beschwert sich VS2012. Vielen Dank, Brad.
CaptainBli
Vielen Dank, dass Sie Ihre Lösung aktualisiert haben. Wie seltsam, dass das Standardformat für Datumsangaben in .NET tatsächlich das Gegenteil für "<" vs ">" ergibt.
Dave Friedel

Antworten:

56

SQLite haben nicht Datetime gewidmet Typen , aber eine hat einige Funktionen Datetime . Befolgen Sie die Zeichenfolgendarstellungsformate (eigentlich nur die Formate 1-10), die von diesen Funktionen verstanden werden (Speichern des Werts als Zeichenfolge), und verwenden Sie sie. Außerdem entspricht der lexikografische Vergleich der Zeichenfolgen dem Datum / Uhrzeit-Vergleich (sofern Sie dies nicht tun) versuchen Sie, Daten mit Zeiten oder Datenzeiten mit Zeiten zu vergleichen, was sowieso nicht viel Sinn macht).

Je nachdem, welche Sprache Sie verwenden, können Sie sogar eine automatische Konvertierung erhalten . (Dies gilt nicht für Vergleiche in SQL-Anweisungen wie im Beispiel, erleichtert Ihnen jedoch das Leben.)


quelle
10
Für alle, die den ersten Satz lesen, hat SQLite in '17 dateunddatetime
alisianoi
3
Gestern wurde hier über Typaffinität gelesen : sqlite.org/datatype3.html Wenn Sie ein Datum benötigen, deklarieren Sie grundsätzlich ein date(oder datetime) in der Spalte, die intern als behandelt wird text. Das passt zu meinen Bedürfnissen.
Alisianoi
99

Um dieses Problem zu lösen, speichere ich Daten als YYYYMMDD. So, where mydate >= '20090101' and mydate <= '20050505'

Es funktioniert einfach die ganze Zeit. Möglicherweise müssen Sie nur einen Parser schreiben, um zu behandeln, wie Benutzer ihre Daten eingeben können, damit Sie sie in konvertieren können YYYYMMDD.

Mark Smith
quelle
2
Wenn sich das Format standardisiert hat, wie würde sich JJJJ-MM-TT von ohne die Bindestriche unterscheiden? Würden Vergleiche nicht gleich enden?
Damon
2
@Damon: Ich denke, er verwendet ein int für den Datentyp
thumbmunkeys
1
Nein, das sind Zeichenfolgen - Sie können es an den Anführungszeichen sehen - Aber das ist die großartige Idee: Mit dieser Bestellung YY MM DD ist es möglich, die Daten zu vergleichen. @Damon sollte es auch mit den Strichen funktionieren!
Sedat Kilinc
1
Ich frage mich, ob ich das Gleiche tun kann, wenn ich das Format yyyyMMddHHmmss zum Speichern verwende, damit ich auch den Zeitteil einschließen kann. Würde es einen Überlauf verursachen oder so?
Faizal
2
Ich benutze: yyyyMMddHHmm ohne Problem, ich würde erwarten, dass yyyyMMddHHmmss gleich funktioniert
Steve Byrne
39

Ich hatte kürzlich das gleiche Problem und habe es folgendermaßen gelöst:

SELECT * FROM table WHERE 
    strftime('%s', date) BETWEEN strftime('%s', start_date) AND strftime('%s', end_date)
Simon
quelle
% s muss zwischen einfachen Anführungszeichen stehen, dh: strftime ('% s', Datum)
mvladic
Es klappt. Geänderte Lösung zur Auswahl aller Zeilen nach einem bestimmten Datum: SELECT * FROM Tabelle WHERE strftime ('% s', hinzugefügt)> strftime ('% s', "2017-01-01 00:00:00")
Neuer Programmierer
Ich bewerte die Verwendung strftimein einer WHERE-Klausel wie in diesem Beispiel und habe eine Frage: Ist es effizient, strftimediese zu verwenden? Wird es einmal für jede Zeile oder einmal pro Abfrage ausgewertet?
Alvaro Gutierrez Perez
Dies sollte als richtige Antwort akzeptiert werden!
Luka Sh
20

Folgendes funktioniert für mich mit SQLite einwandfrei:

SELECT * 
    FROM ingresosgastos 
    WHERE fecharegistro BETWEEN "2010-01-01" AND "2013-01-01"
ifredy
quelle
Dies funktionierte für mich in iOS, Objective-C. Meine Abfrage lautet wie folgt: SELECT COUNT (carSold) FROM cars_sales_tbl WO Datum zwischen '2015-04-01' UND '2015-04-30' UND carType = "Hybrid"
Randika Vishman
9

Sqlite kann nicht auf Daten vergleichen. Wir müssen in Sekunden konvertieren und es als Ganzzahl umwandeln.

Beispiel

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

Das Folgende hat bei mir funktioniert.

SELECT *
FROM table_log
WHERE DATE(start_time) <= '2017-01-09' AND DATE(start_time) >= '2016-12-21'
Jose Jithin Stanly
quelle
Sie könnten stattdessen zwischen verwenden.
Tamim Attafi
6

Ich habe eine Situation, in der ich Daten von vor bis zu zwei Tagen und bis zum Ende des heutigen Tages haben möchte. Ich kam zu folgendem.

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

Ok, technisch gesehen ziehe ich morgen auch Mitternacht ein, wie das Originalplakat, wenn es irgendwelche Daten gab, aber meine Daten sind alle historisch.

Das Wichtigste ist, dass das erste Poster alle Daten nach dem 15.11.2009 um 00:00:00 Uhr ausschloss. Daten, die am 15. um Mitternacht aufgezeichnet wurden, wurden berücksichtigt , Daten nach Mitternacht am 15. jedoch nicht. Wenn ihre Anfrage war,

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

Verwendung der Zwischenklausel zur Klarheit.

Es wäre etwas besser gewesen. Schaltsekunden, in denen eine Stunde tatsächlich mehr als 60 Sekunden haben kann, werden immer noch nicht berücksichtigt, aber gut genug für Diskussionen hier :)

Lyall Pearce
quelle
2

Ich musste die Zeit mit den darin enthaltenen Zeitzoneninformationen speichern und konnte Abfragen mit dem folgenden Format ausführen:

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

Die Zeit wird in der Datenbank als regulärer TEXT im folgenden Format gespeichert:

2015-03-06 20:12:15 -04:00
Eternal21
quelle
2

Nachfolgend finden Sie die Methoden zum Vergleichen der Daten. Zuvor müssen Sie jedoch das Format des in der Datenbank gespeicherten Datums ermitteln

Ich habe Daten im Format MM / TT / JJJJ HH: MM gespeichert, daher muss es in diesem Format verglichen werden

  1. Die folgende Abfrage vergleicht die Konvertierung des Datums in das Format MM / TT / JJJJ und ruft Daten von den letzten fünf Tagen bis heute ab. ZWISCHEN Operator hilft und Sie können einfach Startdatum UND Enddatum angeben.

    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. Die folgende Abfrage wird größer als der Operator (>) verwenden.

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

Ich habe nur die aktuelle Uhrzeit berechnet. Sie können das Format und das Datum nach Bedarf ändern.

Hoffe das wird dir helfen

Summiert

Summierter Jain
quelle
1

Sie können auch Ihre eigenen Benutzerfunktionen erstellen , um Datumsangaben in dem von Ihnen gewählten Format zu verarbeiten. SQLite hat eine ziemlich einfache Methode zum Schreiben eigener Benutzerfunktionen. Zum Beispiel habe ich einige geschrieben, um die Zeitdauer zu addieren.

J. Polfer
quelle
0

Meine Anfrage habe ich wie folgt gemacht:

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

Ich habe den Hinweis von @ ifredys Antwort erhalten. Ich wollte nur, dass diese Abfrage unter iOS mit Objective-C ausgeführt wird. Und es funktioniert!

Hoffe, dass jemand, der iOS-Entwicklung macht, auch von dieser Antwort Gebrauch machen wird!

Randika Vishman
quelle
0

Im Moment entwickle ich mit dem System.Data.SQlite NuGet-Paket (Version 1.0.109.2). Welche mit SQLite Version 3.24.0.

Und das funktioniert bei mir.

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

Ich kann die Funktion datetime () nicht verwenden. Möglicherweise haben sie die SQL-Abfrage für diese SQLite-Version bereits aktualisiert.

Aruman
quelle