Comparaison SQLite DateTime

118

Je n'arrive pas à obtenir des résultats fiables de la requête sur une base de données sqlite en utilisant une chaîne datetime comme comparaison comme suit:

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

comment dois-je gérer les comparaisons datetime avec sqlite?

update: le champ mydate est un type de données DateHeure

Brad
la source
1
Quel format de date la valeur est-elle stockée dans votre mydatecolonne? Je suppose que ce n'est pas l'un des formats pris en charge par SQLite: sqlite.org/lang_datefunc.html
OMG Ponies
1
OMG, c'est un type de données datetime
Brad
4
Cette utilisation de datetime () donnera la valeur exacte que vous lui avez donnée, il n'y a aucune raison de l'utiliser ici: utilisez simplement la chaîne à la place. Et si vous ne traitez que des dates, vous devez supprimer les parties de temps zéro - assurez-vous essentiellement que les deux côtés sont dans le même format. (Sinon '2009-11-13', pour mydate, sera inférieur à '2009-11-13 00:00:00'.)
1
Pour que Visual Studio avec SQLite fonctionne pour Datetime()que j'exécute une requête de date / heure, je dois utiliser le tout comme @Brad l'a inclus dans sa mention de la solution. Sinon VS2012 se plaint. Merci Brad.
CaptainBli
merci d'avoir mis à jour votre avec la solution. Comme il est étrange que le format par défaut des dates dans .NET entraîne en fait le contraire pour le "<" vs ">".
Dave Friedel

Réponses:

58

SQLite n'a pas de types datetime dédiés , mais possède quelques fonctions datetime . Suivez les formats de représentation de chaîne (en fait uniquement les formats 1 à 10) compris par ces fonctions (en stockant la valeur sous forme de chaîne), puis vous pouvez les utiliser, plus la comparaison lexicographique sur les chaînes correspondra à la comparaison datetime (tant que vous ne le faites pas) essayez de comparer les dates aux heures ou les dates-heures aux heures, ce qui n'a de toute façon pas beaucoup de sens).

Selon la langue que vous utilisez, vous pouvez même obtenir une conversion automatique . (Ce qui ne s'applique pas aux comparaisons dans les instructions SQL comme l'exemple, mais vous facilitera la vie.)


la source
10
Pour tous ceux qui lisent la première phrase, dans '17 SQLite a dateetdatetime
alisianoi
3
Hier lisait sur l'affinité de type ici: sqlite.org/datatype3.html Fondamentalement, si vous avez besoin d'une date, vous déclarez un date(ou datetime) sur la colonne qui est traitée en interne comme text. Cela correspond à mes besoins.
alisianoi
100

Pour résoudre ce problème, je stocke les dates au format YYYYMMDD. Donc, where mydate >= '20090101' and mydate <= '20050505'

Cela fonctionne tout simplement tout le temps. Vous n'aurez peut-être besoin que d'écrire un analyseur pour gérer la façon dont les utilisateurs peuvent entrer leurs dates afin que vous puissiez les convertir en YYYYMMDD.

Mark Smith
la source
2
À condition que le format soit normalisé, en quoi le fait d'avoir AAAA-MM-JJ serait-il différent de sans les tirets? Les comparaisons ne finiraient-elles pas par la même chose?
Damon
2
@Damon: je pense qu'il utilise un int pour le type de données
thumbmunkeys
1
Non, ce sont des chaînes - vous pouvez le voir dans les guillemets - Mais c'est la bonne idée: avec cette commande AA MM JJ, il est possible de comparer les dates. @Damon ça devrait aussi fonctionner avec les tirets!
Sedat Kilinc
1
Je me demande si je peux faire la même chose si j'utilise le format aaaaMMjjHHmmss pour stocker, afin que je puisse également inclure la partie temporelle. Cela provoquerait-il un débordement ou quelque chose comme ça?
faizal
2
J'utilise: aaaaMMjjHHmm sans problème, je m'attendrais à ce que aaaaMMjjHHmmss fonctionne de la même manière
Steve Byrne
39

J'ai eu le même problème récemment, et je l'ai résolu comme ceci:

SELECT * FROM table WHERE 
    strftime('%s', date) BETWEEN strftime('%s', start_date) AND strftime('%s', end_date)
Simon
la source
% s doit être placé entre guillemets simples, c'est-à-dire: strftime ('% s', date)
mvladic
Ça marche. Solution modifiée pour sélectionner toutes les lignes après une certaine date: SELECT * FROM table WHERE strftime ('% s', added)> strftime ('% s', "2017-01-01 00:00:00")
New Progammer
J'évalue l'utilisation strftimedans une clause WHERE comme dans cet exemple, et j'ai une question: est-il efficace d'utiliser strftimecomme ça? Est-il évalué une fois pour chaque ligne ou une fois par requête?
Alvaro Gutierrez Perez
cela devrait être accepté comme une bonne réponse!
Luka Sh le
20

Ce qui suit fonctionne très bien pour moi en utilisant SQLite:

SELECT * 
    FROM ingresosgastos 
    WHERE fecharegistro BETWEEN "2010-01-01" AND "2013-01-01"
ifredy
la source
Cela a fonctionné pour moi dans iOS, Objective-C Ma requête est la suivante: SELECT COUNT (carSold) FROM cars_sales_tbl WHERE date BETWEEN '2015-04-01' AND '2015-04-30' AND carType = "Hybrid"
Randika Vishman
9

Sqlite ne peut pas comparer sur les dates. nous devons convertir en secondes et le convertir en nombre entier.

Exemple

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

La suite a fonctionné pour moi.

SELECT *
FROM table_log
WHERE DATE(start_time) <= '2017-01-09' AND DATE(start_time) >= '2016-12-21'
Jose Jithin Stanly
la source
vous pouvez utiliser entre les deux à la place.
Tamim Attafi
6

J'ai une situation où je veux des données d'il y a jusqu'à deux jours et jusqu'à la fin d'aujourd'hui. Je suis arrivé à ce qui suit.

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

Ok, techniquement, je tire aussi à minuit demain comme l'affiche originale, s'il y avait des données, mais mes données sont toutes historiques.

La chose clé à retenir, l'affiche initiale excluait toutes les données après le 15/11/2009 à 00:00:00. Ainsi, toutes les données enregistrées à minuit le 15 ont été incluses, mais toutes les données après minuit le 15 ne l'étaient pas. Si leur requête était,

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

Utilisation de la clause between pour plus de clarté.

Cela aurait été un peu mieux. Cela ne prend toujours pas en compte les secondes intercalaires dans lesquelles une heure peut en réalité avoir plus de 60 secondes, mais assez bien pour les discussions ici :)

Lyall Pearce
la source
2

J'ai dû stocker l'heure avec les informations de fuseau horaire, et j'ai pu obtenir des requêtes fonctionnant avec le format suivant:

"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'heure est stockée dans la base de données sous forme de TEXTE normal au format suivant:

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

Voici les méthodes pour comparer les dates, mais avant cela, nous devons identifier le format de la date stockée dans DB

J'ai des dates stockées au format MM / JJ / AAAA HH: MM, il faut donc les comparer dans ce format

  1. La requête ci-dessous compare la conversion de la date au format MM / JJ / AAA et obtient les données des cinq derniers jours jusqu'à aujourd'hui. L'opérateur BETWEEN vous aidera et vous pouvez simplement spécifier la date de début ET la date de fin.

    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 requête ci-dessous utilisera l'opérateur supérieur à (>).

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

Tout le calcul que j'ai fait utilise l'heure actuelle, vous pouvez changer le format et la date selon vos besoins.

J'espère que ceci vous aidera

Résumé

Jain sommé
la source
1

Vous pouvez également rédiger vos propres fonctions utilisateur pour gérer les dates dans le format que vous choisissez. SQLite a une méthode assez simple pour écrire vos propres fonctions utilisateur. Par exemple, j'en ai écrit quelques-uns pour additionner les durées de temps.

J. Polfer
la source
0

Ma requête j'ai fait comme suit:

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

J'ai eu la réponse de @ ifredy. Tout ce que j'ai fait, c'est que je voulais que cette requête soit exécutée dans iOS, en utilisant Objective-C. Et il fonctionne!

J'espère que quelqu'un qui fait du développement iOS utilisera également cette réponse!

Randika Vishman
la source
0

En ce moment, je développe en utilisant le package NuGet System.Data.SQlite (version 1.0.109.2). Qui en utilisant la version 3.24.0 de SQLite.

Et cela fonctionne pour moi.

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

Je n'ai pas l'intention d'utiliser la fonction datetime (). Peut-être ont-ils déjà mis à jour la requête SQL sur cette version de SQLite.

Aruman
la source