2011-11-18 26 views
50

Estoy ejecutando sqlite para seleccionar datos entre dos rangos para un informe de ventas. Para seleccionar los datos de fechas entre dos utilizo la siguiente declaración:SQL Seleccionar entre las fechas

SELECT * FROM test WHERE date BETWEEN "11/1/2011" AND "11/8/2011"; 

Esta declaración agarra todas las fechas incluso aquellos fuera de los criterios. El formato de fecha que ve ingresado está en el mismo formato que recupero. No estoy seguro de lo que sucede, pero agradezco cualquier ayuda que pueda encontrar. ¡Gracias!

+1

Sólo un consejo relacionado rápida la longitud entre '/'. Si siempre puedes usar aaaa/MM/dd como formato. Parará los molestos problemas de diferencias regionales que podrían ser su problema. – Haedrian

Respuesta

69

SQLLite requiere que las fechas estén en el formato YYYY-MM-DD. Como los datos en su base de datos y la cadena de su consulta no están en ese formato, probablemente trate sus "fechas" como cadenas.

+0

Después de cambiar el formato de fecha volví a ejecutar la consulta como 'SELECCIONAR fecha FROM prueba WHERE fecha ENTRE "2011-11-1" Y "2011-11-2";' y obtuve resultados para 2011-11-16:/ – Zombian

+26

Es el 10 y el 20 del mes. Pruebe 'BETWEEN '2011-11-01' AND '2011-11-02''. –

+0

@LarryLustig me dices cómo arreglar el mío, tengo el mismo problema con el servidor sql 2014 –

25

Cambie sus datos a esos formatos para usar sqlite datetime formats.

YYYY-MM-DD 
YYYY-MM-DD HH:MM 
YYYY-MM-DD HH:MM:SS 
YYYY-MM-DD HH:MM:SS.SSS 
YYYY-MM-DDTHH:MM 
YYYY-MM-DDTHH:MM:SS 
YYYY-MM-DDTHH:MM:SS.SSS 
HH:MM 
HH:MM:SS 
HH:MM:SS.SSS 
now 
DDDDDDDDDD 

SELECT * FROM test WHERE date BETWEEN '2011-01-11' AND '2011-08-11' 
+0

La idea correcta, pero dado que los datos vuelven también está en formato 'MM/DD/YYYY', sospecho que esto aún no funcionará ya que los datos en su base de datos se tratarán como cadenas en lugar de fechas. –

+0

@EricPetroelje Sí, pero una vez que coincida con el formato en la base de datos para el formato en la consulta, funcionaría.Parece que fue editado más tarde para incluir lo que debe ser la consulta actualizada una vez que se actualiza el DB, aunque la consulta necesita comillas simples en lugar de comillas dobles. – vapcguy

9

una forma más para seleccionar entre las fechas en SQLite es el uso de los poderosos strftime función:

SELECT * FROM test WHERE strftime('%Y-%m-%d', date) BETWEEN "11-01-2011" AND "11-08-2011" 

Estos son equivalentes según https://sqlite.org/lang_datefunc.html:

date(...) 

strftime('%Y-%m-%d', ...) 

pero si quieres más opciones, lo tienes.

+0

Las comillas deben ser comillas simples, pero de lo contrario la consulta debería funcionar. – vapcguy

4

O puede convertir su cadena al formato de fecha con fecha función. Incluso la fecha se almacena como TEXTO en la base de datos. gusta esta (la variante más viable):

SELECT * FROM test WHERE date(date) 
BETWEEN date('2011-01-11') AND date('2011-8-11') 
+0

Creo que el problema con esta solución es que no se indica el formato de fecha del TEXTO (por ejemplo, si la cadena de fecha se almacena como 'MM/DD/YYYY'). Probé este enfoque y no funciona para mí, y creo que esa es la razón. –

1
SELECT * 
FROM TableName 
WHERE julianday(substr(date,7)||'-'||substr(date,4,2)||'-'||substr(date,1,2)) BETWEEN julianday('2011-01-11') AND julianday('2011-08-11') 

Nota que utilizo el formato: dd/mm/yyyy

Si utiliza d/m/aaaa, Cambio de substr()

Esperanza esta Te ayudará.

+0

¡Excelente uso de splicing! Votado arriba. Sin embargo, tenga en cuenta que no necesita usar 'julianday()', y usar eso supone que su fecha está en UTC porque 'julianday()' calcula contra una hora basada en GMT, por lo que puede incluir las fechas que usa No desea, e incluye las fechas en que lo hace, si las fechas están en la hora local. Debería poder hacer 'SELECT * FROM TableName WHERE substr (date, 7) || '-' || substr (date, 4,2) || '-' || substr (date, 1,2) ENTRE '2011-01-11' Y '2011-08-11'' y debería funcionar. – vapcguy

+0

Agradecimiento especial a [Jeff] (http://stackoverflow.com/users/781965/jeff) y [vapcguy] (http://stackoverflow.com/users/1181535/vapcguy) su interactividad es realmente alentadora –

1

Gracias especiales a Jeff y vapcguy su interactividad es realmente alentadora.

Aquí es una declaración más compleja que es útil cuando se desconoce ::

SELECT * FROM tableName 
WHERE julianday(
    substr(substr(date, instr(date, '/')+1), instr(substr(date, instr(date, '/')+1), '/')+1) 
||'-'|| 
    case when length(
    substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1),'/')-1) 
    )=2 
    then 
    substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1) 
    else 
    '0'||substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1) 
    end 
||'-'|| 
    case when length(substr(date,1, instr(date, '/')-1)) =2 
    then substr(date,1, instr(date, '/')-1) 
    else 
    '0'||substr(date,1, instr(date, '/')-1) 
    end 
) BETWEEN julianday('2015-03-14') AND julianday('2015-03-16') 
+0

Gracias por la cumplido, y tengo que dárselo a usted por su capacidad de hacer subcadenas. Sin embargo, mi mismo comentario sobre 'julianday()' de la otra publicación todavía se aplica. Esta es básicamente la misma respuesta que la otra, excepto que se pone en lógica condicional para agregar ceros a la izquierda para días y meses de un solo dígito. Probablemente debería haber sido agregado a la otra respuesta, o reemplazado con esta edición. Upvoted, ya que es más correcto, sin embargo. – vapcguy

Cuestiones relacionadas