SQLite DateTime confronto


117

Non riesco a ottenere risultati affidabili dalla query su un database sqlite utilizzando una stringa datetime come confronto in questo modo:

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

come dovrei gestire i confronti datetime con sqlite?

aggiornamento: il campo mydate è un tipo di dati DateTime


1
Quale formato di data è il valore memorizzato nella tua mydatecolonna? Immagino che non sia uno dei formati supportati da SQLite: sqlite.org/lang_datefunc.html
OMG Ponies

1
OMG, è un tipo di dati datetime
Brad

4
L'utilizzo di datetime () risulterà nel valore esatto che gli hai dato, non c'è motivo di usarlo qui: usa semplicemente la stringa. E se hai a che fare solo con le date, dovresti eliminare le parti di tempo zero --- essenzialmente assicurati che entrambe le parti siano nello stesso formato. (Altrimenti '2009-11-13', per la mia data, sarà inferiore a '2009-11-13 00:00:00'.)

1
Affinché Visual Studio con SQLite funzioni per me per eseguire una query di data / ora, devo utilizzare lo stesso Datetime()come @Brad ha incluso nella sua menzione della soluzione. Altrimenti VS2012 si lamenta. Grazie Brad.
CaptainBli

grazie per aver aggiornato il tuo con la soluzione. È strano che il formato predefinito per le date in .NET risulti effettivamente opposto per "<" vs ">".
Dave Friedel

Risposte:


57

SQLite non ha tipi datetime dedicati , ma ha alcune funzioni datetime . Segui i formati di rappresentazione delle stringhe (in realtà solo i formati 1-10) compresi da quelle funzioni (memorizzando il valore come una stringa) e poi puoi usarli, inoltre il confronto lessicografico sulle stringhe corrisponderà al confronto data / ora (a patto che tu non lo faccia prova a confrontare le date con le ore o le date con le ore, il che non ha molto senso comunque).

A seconda della lingua che utilizzi, puoi persino ottenere la conversione automatica . (Che non si applica ai confronti nelle istruzioni SQL come l'esempio, ma ti semplificherà la vita.)


10
Per tutti coloro che leggono la prima frase, nel '17 SQLite ha dateedatetime
alisianoi

3
Ieri stavo leggendo l'affinità di tipo qui: sqlite.org/datatype3.html Fondamentalmente, se hai bisogno di una data, dichiari un date(o datetime) sulla colonna che internamente è trattata come text. Questo si adatta alle mie esigenze.
alisianoi

100

Per risolvere questo problema, memorizzo le date come YYYYMMDD. Così, where mydate >= '20090101' and mydate <= '20050505'

Semplicemente FUNZIONA tutto il tempo. Potrebbe essere necessario solo scrivere un parser per gestire il modo in cui gli utenti potrebbero inserire le loro date in modo da poterle convertire in YYYYMMDD.


2
A condizione che il formato sia standardizzato, in che modo sarebbe diverso AAAA-MM-GG senza i trattini? I confronti non sarebbero finiti allo stesso modo?
Damon

2
@Damon: penso che usi un int per il tipo di dati
thumbmunkeys

1
No, queste sono stringhe - puoi vederlo tra virgolette - Ma questa è la grande idea: con questo ordine AA MM GG è possibile confrontare le date. @ Damon dovrebbe funzionare anche con i trattini!
Sedat Kilinc

1
Mi chiedo se posso fare la stessa cosa se utilizzo il formato aaaaMMggHHmmss per memorizzare, in modo da poter includere anche la parte temporale. Causerebbe un trabocco o qualcosa del genere?
faizal

2
Io uso: yyyyMMddHHmm senza problemi, mi aspetto che yyyyMMddHHmmss funzioni allo stesso modo
Steve Byrne

39

Ho avuto lo stesso problema di recente e l'ho risolto in questo modo:

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

% s deve essere racchiuso tra virgolette singole, ad esempio: strftime ('% s', data)
mvladic

Funziona. Soluzione modificata per selezionare tutte le righe dopo una certa data: SELECT * FROM table WHERE strftime ('% s', added)> strftime ('% s', "2017-01-01 00:00:00")
New Progammer

Sto valutando l'utilizzo strftimein una clausola WHERE come in questo esempio e ho una domanda: è efficiente da usare in strftimequesto modo? Viene valutato una volta per ogni riga o una volta per query?
Alvaro Gutierrez Perez

questa dovrebbe essere accettata come risposta corretta!
Luka Sh

20

Quanto segue funziona bene per me che uso SQLite:

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

Questo ha funzionato per me in iOS, Objective-C My Query è il seguente: SELECT COUNT (carSold) FROM cars_sales_tbl WHERE date TRA '2015-04-01' AND '2015-04-30' AND carType = "Hybrid"
Randika Vishman

9

Sqlite non può confrontare le date. dobbiamo convertire in secondi e lanciarlo come numero intero.

Esempio

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

8

Seguire ha funzionato per me.

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

potresti usare tra invece.
Tamim Attafi

6

Ho una situazione in cui desidero i dati fino a due giorni fa e fino alla fine di oggi. Sono arrivato al seguente.

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

Ok, tecnicamente torno anche domani a mezzanotte come il poster originale, se c'erano dei dati, ma i miei dati sono tutti storici.

La cosa fondamentale da ricordare, il poster iniziale escludeva tutti i dati dopo il 15-11-2009 00:00:00. Quindi, tutti i dati registrati a mezzanotte del 15 sono stati inclusi, ma i dati dopo la mezzanotte del 15 non lo erano. Se la loro domanda era,

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

Uso della clausola tra per chiarezza.

Sarebbe stato leggermente migliore. Non tiene ancora conto dei secondi intercalari in cui un'ora può effettivamente avere più di 60 secondi, ma abbastanza buono per le discussioni qui :)


2

Ho dovuto memorizzare l'ora con le informazioni sul fuso orario e sono stato in grado di ottenere query che funzionassero con il seguente formato:

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

L'ora viene memorizzata nel database come un normale TESTO nel seguente formato:

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

2

Di seguito sono riportati i metodi per confrontare le date, ma prima dobbiamo identificare il formato della data memorizzato nel DB

Ho le date memorizzate nel formato MM / GG / AAAA HH: MM, quindi devono essere confrontate in quel formato

  1. La query sottostante confronta la conversione della data nel formato MM / GG / AAA e ottiene i dati dagli ultimi cinque giorni fino ad oggi. L'operatore BETWEEN ti aiuterà e puoi semplicemente specificare la data di inizio E la data di fine.

    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. La query sottostante utilizzerà l'operatore maggiore di (>).

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

Tutto il calcolo che ho fatto è usare l'ora corrente, puoi cambiare il formato e la data secondo le tue necessità.

Spero che questo ti possa aiutare

Summved


1

Puoi anche scrivere le tue funzioni utente per gestire le date nel formato che scegli. SQLite ha un metodo abbastanza semplice per scrivere le proprie funzioni utente. Ad esempio, ne ho scritti alcuni per aggiungere le durate di tempo insieme.


0

La mia domanda ho fatto come segue:

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

Ho ricevuto il suggerimento dalla risposta di @ ifredy. Tutto quello che ho fatto è che volevo che questa query venisse eseguita in iOS, utilizzando Objective-C. E funziona!

Spero che qualcuno che si occupa di sviluppo iOS, sfrutti anche questa risposta!


0

In questo momento sto sviluppando utilizzando il pacchetto NuGet System.Data.SQlite (versione 1.0.109.2). Quale utilizzando SQLite versione 3.24.0.

E questo funziona per me.

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

Non voglio usare la funzione datetime (). Forse hanno già aggiornato la query SQL su quella versione SQLite.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.