Comparación de SQLite DateTime

117

Parece que no puedo obtener resultados confiables de la consulta contra una base de datos sqlite usando una cadena de fecha y hora como comparación de la siguiente manera:

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

¿Cómo debo manejar las comparaciones de fecha y hora con sqlite?

actualización: el campo mydate es un tipo de datos DateTime

Puntilla
fuente
1
¿Qué formato de fecha tiene el valor almacenado en su mydatecolumna? Supongo que no es uno de los formatos compatibles con SQLite: sqlite.org/lang_datefunc.html
OMG Ponies
1
Dios mío, es un tipo de datos de fecha y hora
Brad
4
Ese uso de datetime () dará como resultado el valor exacto que le dio, no hay razón para usarlo aquí: simplemente use la cadena en su lugar. Y si solo está tratando con fechas, debe eliminar las partes de tiempo cero, esencialmente asegúrese de que ambos lados estén en el mismo formato. (De lo contrario '2009-11-13', para mydate, será menor que '2009-11-13 00:00:00'.)
1
Para que Visual Studio con SQLite funcione para que pueda ejecutar una consulta de fecha / hora, necesito usar el Datetime()tal como @Brad ha incluido en su mención de la solución. De lo contrario VS2012 se queja. Gracias Brad.
CaptainBli
gracias por actualizar su con la solución. Qué extraño que el formato predeterminado para las fechas en .NET realmente resulte en lo opuesto para el "<" vs ">".
Dave Friedel

Respuestas:

57

SQLite no tiene tipos de fecha y hora dedicados , pero tiene algunas funciones de fecha y hora . Siga los formatos de representación de cadenas (en realidad, solo los formatos 1-10) comprendidos por esas funciones (almacenando el valor como una cadena) y luego puede usarlos, además la comparación lexicográfica en las cadenas coincidirá con la comparación de fecha y hora (siempre que no lo haga intente comparar fechas con horas o fechas con horas, lo cual no tiene mucho sentido de todos modos).

Dependiendo del idioma que use, incluso puede obtener una conversión automática . (Lo cual no se aplica a las comparaciones en declaraciones SQL como el ejemplo, pero le facilitará la vida).


fuente
10
Para todos aquellos que leen la primera oración, en '17 SQLite tiene dateydatetime
alisianoi
3
Ayer estaba leyendo sobre la afinidad de tipos aquí: sqlite.org/datatype3.html Básicamente, si necesita una fecha, declara un date(o datetime) en la columna que internamente se trata como text. Eso se ajusta a mis necesidades.
alisianoi
100

Para resolver este problema, guardo las fechas como YYYYMMDD. Así, where mydate >= '20090101' and mydate <= '20050505'

Simplemente FUNCIONA todo el tiempo. Es posible que solo necesite escribir un analizador para manejar cómo los usuarios pueden ingresar sus fechas para que pueda convertirlas a YYYYMMDD.

Mark Smith
fuente
2
Siempre que el formato esté estandarizado, ¿en qué se diferenciaría el formato AAAA-MM-DD de sin los guiones? ¿No terminarían igual las comparaciones?
Damon
2
@Damon: creo que usa un int para el tipo de datos
thumbmunkeys
1
No, estas son cadenas - lo puedes ver en las comillas - Pero esta es la gran idea: Con este orden YY MM DD es posible comparar las fechas. @Damon ¡también debería funcionar con los guiones!
Sedat Kilinc
1
Me pregunto si puedo hacer lo mismo si utilizo el formato aaaaMMddHHmmss para almacenar, de modo que también pueda incluir la parte de tiempo. ¿Causaría un desbordamiento o algo así?
faizal
2
Yo uso: aaaaMMddHHmm sin ningún problema, esperaría que aaaaMMddHHmmss funcione igual
Steve Byrne
39

Tuve el mismo problema recientemente y lo resolví así:

SELECT * FROM table WHERE 
    strftime('%s', date) BETWEEN strftime('%s', start_date) AND strftime('%s', end_date)
Simón
fuente
% s debe estar entre comillas simples, es decir: strftime ('% s', fecha)
mvladic
Funciona. Solución modificada para seleccionar todas las filas después de una fecha determinada: SELECT * FROM table WHERE strftime ('% s', added)> strftime ('% s', "2017-01-01 00:00:00")
New Progammer
Estoy evaluando el uso strftimeen una cláusula WHERE como en este ejemplo, y tengo una pregunta: ¿Es eficiente usarlo strftimeasí? ¿Se evalúa una vez por cada fila o una vez por consulta?
Álvaro Gutiérrez Pérez
¡esto debe aceptarse como respuesta correcta!
Luka Sh
20

Lo siguiente funciona bien para mí usando SQLite:

SELECT * 
    FROM ingresosgastos 
    WHERE fecharegistro BETWEEN "2010-01-01" AND "2013-01-01"
ifredy
fuente
Esto funcionó para mí en iOS, Objective-C Mi consulta es la siguiente: SELECT COUNT (carSold) FROM cars_sales_tbl WHERE date BETWEEN '2015-04-01' AND '2015-04-30' AND carType = "Hybrid"
Randika Vishman
9

Sqlite no se puede comparar en fechas. necesitamos convertirlo en segundos y convertirlo en un número entero.

Ejemplo

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

Seguir funcionó para mí.

SELECT *
FROM table_log
WHERE DATE(start_time) <= '2017-01-09' AND DATE(start_time) >= '2016-12-21'
José Jithin Stanly
fuente
podría usar entre en su lugar.
Tamim Attafi
6

Tengo una situación en la que quiero datos de hasta dos días atrás y hasta el final de hoy. Llegué a lo siguiente.

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

Ok, técnicamente también saco la medianoche de mañana como el póster original, si había algún dato, pero todos mis datos son históricos.

La clave para recordar, el cartel inicial excluyó todos los datos después del 15-11-2009 00:00:00. Por lo tanto, se incluyeron todos los datos que se registraron a la medianoche del día 15, pero no los datos posteriores a la medianoche del día 15. Si su consulta fue,

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

Uso de la cláusula entre para mayor claridad.

Hubiera sido un poco mejor. Todavía no tiene en cuenta los segundos intercalares en los que una hora puede tener más de 60 segundos, pero lo suficientemente bueno para las discusiones aquí :)

Lyall Pearce
fuente
2

Tuve que almacenar la hora con la información de la zona horaria y pude hacer que las consultas funcionaran con el siguiente 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')"

La hora se almacena en la base de datos como TEXTO normal en el siguiente formato:

2015-03-06 20:12:15 -04:00
Eterno21
fuente
2

A continuación se muestran los métodos para comparar las fechas, pero antes necesitamos identificar el formato de la fecha almacenada en la base de datos

Tengo fechas almacenadas en formato MM / DD / YYYY HH: MM, por lo que debe compararse en ese formato

  1. La siguiente consulta compara la conversión de la fecha en formato MM / DD / YYY y obtiene datos de los últimos cinco días hasta hoy. El operador BETWEEN lo ayudará y simplemente puede especificar la fecha de inicio Y la fecha de finalización.

    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 siguiente consulta utilizará un operador mayor que (>).

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

Todo el cálculo que he hecho es usar la hora actual, puede cambiar el formato y la fecha según sus necesidades.

Espero que esto te ayudará

Summved

Summved Jain
fuente
1

También puede escribir sus propias funciones de usuario para manejar fechas en el formato que elija. SQLite tiene un método bastante simple para escribir sus propias funciones de usuario. Por ejemplo, escribí algunos para sumar duraciones de tiempo.

J. Polfer
fuente
0

Mi consulta hice lo siguiente:

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

Recibí la pista por la respuesta de @ ifredy. Lo único que hice fue que quería que esta consulta se ejecutara en iOS, usando Objective-C. ¡Y funciona!

¡Espero que alguien que desarrolle iOS también aproveche esta respuesta!

Randika Vishman
fuente
0

En este momento estoy desarrollando usando el paquete System.Data.SQlite NuGet (versión 1.0.109.2). Que usando SQLite versión 3.24.0.

Y esto funciona para mí.

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

No puedo usar la función datetime (). Quizás ya actualizaron la consulta SQL en esa versión de SQLite.

Aruman
fuente