Comparação SQLite DateTime


117

Não consigo obter resultados confiáveis ​​da consulta em um banco de dados sqlite usando uma string datetime como uma comparação:

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

como devo lidar com as comparações de data e hora com sqlite?

update: o campo mydate é um tipo de dados DateTime


1
Qual formato de data é o valor armazenado em sua mydatecoluna? Suponho que não seja um dos formatos suportados pelo SQLite: sqlite.org/lang_datefunc.html
OMG Ponies

1
OMG, é um tipo de dados datetime
Brad

4
Esse uso de datetime () resultará no valor exato que você forneceu, não há razão para usá-lo aqui: apenas use a string. E se você está lidando apenas com datas, você deve excluir as partes do tempo zero - essencialmente, certifique-se de que os dois lados estejam no mesmo formato. (Caso contrário '2009-11-13', para minha data, será menor que '2009-11-13 00:00:00'.)

1
Para que o Visual Studio com SQLite funcione para que eu execute uma consulta de data / hora, preciso usar o Datetime()exatamente como @Brad incluiu em sua menção à solução. Caso contrário, o VS2012 reclama. Obrigado Brad.
CaptainBli

obrigado por atualizar seu com a solução. É estranho que o formato padrão para datas em .NET resulte no oposto para "<" vs ">".
Dave Friedel

Respostas:


57

SQLite não tem tipos de data e hora dedicados , mas tem algumas funções de data e hora . Siga os formatos de representação de string (na verdade, apenas os formatos 1-10) compreendidos por essas funções (armazenando o valor como uma string) e então você pode usá-los, mais a comparação lexicográfica nas strings irá corresponder à comparação de data e hora (contanto que você não tente comparar datas com horas ou datas com horas, o que não faz muito sentido de qualquer maneira).

Dependendo de qual idioma você usa, você pode até obter conversão automática . (O que não se aplica a comparações em instruções SQL como o exemplo, mas tornará sua vida mais fácil.)


10
Para todos aqueles que estão lendo a primeira frase, em '17 SQLite tem dateedatetime
alisianoi

3
Ontem li sobre afinidade de tipo aqui: sqlite.org/datatype3.html Basicamente, se precisar de uma data, você declara um date(ou datetime) na coluna que internamente é tratado comotext . Isso atende às minhas necessidades.
alisianoi

100

Para resolver esse problema, armazeno as datas como YYYYMMDD. Portanto, where mydate >= '20090101' and mydate <= '20050505'

Simplesmente FUNCIONA o tempo todo. Você só precisa escrever um analisador para controlar como os usuários podem inserir suas datas para que você possa convertê-las em YYYYMMDD.


2
Desde que o formato seja padronizado, como ter AAAA-MM-DD seria diferente de sem os travessões? As comparações não seriam iguais?
Damon

2
@Damon: acho que ele usa um int para tipo de dados
thumbmunkeys,

1
Não, são strings - você pode ver nas aspas - Mas esta é a grande ideia: Com este pedido AA MM DD é possível comparar as datas. @Damon também deve funcionar com os travessões!
Sedat Kilinc

1
Gostaria de saber se posso fazer a mesma coisa se usar o formato aaaaMMddHHmmss para armazenar, de modo que possa incluir a parte do tempo também. Isso causaria um estouro ou algo assim?
faizal

2
Eu uso: yyyyMMddHHmm sem problemas, espero que yyyyMMddHHmmss funcione da mesma forma
Steve Byrne

39

Tive o mesmo problema recentemente e resolvi assim:

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

% s deve ser colocado entre aspas simples, ou seja: strftime ('% s', data)
mvladic

Funciona. Solução modificada para selecionar todas as linhas após determinada data: SELECT * FROM tabela WHERE strftime ('% s', adicionado)> strftime ('% s', "2017-01-01 00:00:00")
Novo Progammer

Estou avaliando o uso strftimede uma cláusula WHERE como neste exemplo e tenho uma pergunta: É eficiente usar strftimeassim? Ele é avaliado uma vez para cada linha ou uma vez por consulta?
Alvaro Gutierrez Perez

isso deve ser aceito como resposta correta!
Luka Sh

20

O seguinte está funcionando bem para mim usando SQLite:

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

Isso funcionou para mim no iOS, Objective-C My Query é o seguinte: SELECT COUNT (carSold) FROM cars_sales_tbl ONDE data BETWEEN '2015-04-01' AND '2015-04-30' AND carType = "Hybrid"
Randika Vishman

9

Sqlite não pode comparar datas. precisamos converter em segundos e convertê-lo como inteiro.

Exemplo

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

8

Seguir funcionou para mim.

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

você pode usar entre em vez disso.
Tamim Attafi

6

Tenho uma situação em que desejo dados de até dois dias atrás e até o final de hoje. Cheguei ao seguinte.

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

Ok, tecnicamente eu também puxo amanhã à meia-noite como o pôster original, se houver algum dado, mas meus dados são todos históricos.

O principal a ser lembrado é que o pôster inicial excluiu todos os dados após 15-11-2009 00:00:00. Portanto, quaisquer dados que foram registrados à meia-noite do dia 15 foram incluídos, mas quaisquer dados após a meia-noite do dia 15 não foram. Se sua consulta fosse,

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

Uso da cláusula between para maior clareza.

Teria sido um pouco melhor. Ele ainda não leva em consideração os segundos bissextos em que uma hora pode realmente ter mais de 60 segundos, mas bom o suficiente para discussões aqui :)


2

Tive que armazenar a hora com as informações de fuso horário e consegui fazer as consultas funcionarem com o seguinte 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')"

A hora é armazenada no banco de dados como TEXTO normal no seguinte formato:

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

2

Abaixo estão os métodos para comparar as datas, mas antes disso precisamos identificar o formato da data armazenada no DB

Eu tenho datas armazenadas no formato MM / DD / AAAA HH: MM, então elas devem ser comparadas nesse formato

  1. A consulta abaixo compara a conversão da data no formato MM / DD / AAA e obtém os dados dos últimos cinco dias até hoje. O operador BETWEEN ajudará e você pode simplesmente especificar a data de início E a data de término.

    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. A consulta abaixo usará o operador maior que (>).

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

Todo o cálculo que fiz está usando a hora atual, você pode alterar o formato e a data de acordo com sua necessidade.

Espero que isso te ajude

Summved


1

Você também pode escrever suas próprias funções de usuário para lidar com datas no formato que você escolher. SQLite possui um método bastante simples para escrever suas próprias funções de usuário. Por exemplo, escrevi alguns para adicionar durações de tempo juntos.


0

Minha consulta fiz da seguinte maneira:

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

Recebi a dica com a resposta de @ ifredy. Tudo o que fiz foi, queria que essa consulta fosse executada no iOS, usando Objective-C. E funciona!

Espero que alguém que faz desenvolvimento para iOS também aproveite esta resposta!


0

No momento estou desenvolvendo usando o pacote System.Data.SQlite NuGet (versão 1.0.109.2). Que usando SQLite versão 3.24.0.

E isso funciona para mim.

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

Não pretendo usar a função datetime (). Talvez eles já tenham atualizado a consulta SQL nessa versão do SQLite.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.