Se eu executar uma consulta com uma between
cláusula, parece excluir o valor final.
Por exemplo:
select * from person where dob between '2011-01-01' and '2011-01-31'
Isso obtém todos os resultados dob
de '2011-01-01' a '2011-01-30'; pulando registros onde dob
é '2011-01-31'. Alguém pode explicar por que essa consulta se comporta dessa maneira e como eu poderia modificá-la para incluir registros onde dob
está '2011-01-31'? (sem adicionar 1 à data final porque ela foi selecionada pelos usuários.)
BETWEEN
É inclusiva para ambos os valores. Eu tenhoMySQL Server 5.7
no Windows 10.Respostas:
O campo
dob
provavelmente tem um componente de tempo.Para truncá-lo:
fonte
CAST(dob AS DATE)
você pode usar o mais sucintoDATE(dob)
.>=
e<
nãobetween
.dob BETWEEN '2011-01-01 00:00:00' AND '2011-01-31 23:59:59
. Isso ocorre porqueDATE(dob)
é necessário calcular um valor para cada linha e não pode usar nenhum índice nesse campo.t > 23:59:59 and t < 24:00:00
. Por que lidar com mal especificadoBETWEEN
? Em vez seguir o conselho e uso de David:WHERE dob >= '2011-01-01' AND dob < '2011-02-01'
. Melhor desempenho e funciona sempre.No manual do MySQL :
fonte
O problema é que 2011-01-31 é realmente 2011-01-31 00:00:00. Esse é o começo do dia. Tudo durante o dia não está incluído.
fonte
fonte
2011-01-31 23:59:59
mas incluirá as que2011-01-31 23:59:58
não estiverem incluídas até o último segundo do dia. Pode ser menor, mas alguém se beneficiará.23:59:59
no resultado. Portanto, as duas maneiras são inclusivas.dob
coluna for um carimbo de data / hora com precisão de menos de um segundo,BETWEEN
ainda assim não ocorrerá eventos no segundo final do dia, a menos que '2011-02-01 00:00:00' seja usado?2011-01-31 23:59:59.003
. @nitrogen usando2011-02-01 000:00:00
irá incorretamente incluem tempo zero em 1º de fevereiro .... E é por isso>=
e<
deve ser usado em seu lugar.O campo que você está referenciando na sua consulta é um tipo de data ou um tipo de data e hora ?
Uma causa comum do comportamento que você descreve é quando você usa um tipo DateTime em que realmente deveria estar usando um tipo Date. Ou seja, a menos que você realmente precise saber a que horas alguém nasceu, basta usar o tipo Data.
O motivo pelo qual o dia final não está sendo incluído nos seus resultados é o modo como a consulta está assumindo a parte do tempo das datas que você não especificou na sua consulta.
Ou seja: sua consulta está sendo interpretada como Meia-noite entre 30/01/2011 e 31/01/2011, mas os dados podem ter um valor posteriormente no dia 2011/01/01.
Sugestão: Altere o campo para o tipo Data se for do tipo DateTime.
fonte
Olá, esta consulta funciona para mim,
fonte
Surpreendentemente, essas conversões são soluções para muitos problemas no MySQL.
fonte
Defina a data superior como + 1 dia; portanto, no seu caso, defina-a para 01-02-2011.
fonte
BETWEEN
deve ser ignorado; mas>=
e<
deve ser usado em seu lugar.Você pode executar a consulta como:
como outros apontaram, se suas datas são codificadas.
Por outro lado, se a data estiver em outra tabela, você poderá adicionar um dia e subtrair um segundo (se as datas forem salvas sem o segundo / horário), como:
Evite fazer transmissões nos
dob
campos (como na resposta aceita), pois isso pode causar grandes problemas de desempenho (como não poder usar um índice emdob
campo, supondo que exista). O plano de execução pode mudar deusing index condition
parausing where
se você criar algo comoDATE(dob)
ouCAST(dob AS DATE)
, portanto, tenha cuidado!fonte
No MySql, os valores são inclusivos, portanto, quando você tenta obter entre '2011-01-01' e '2011-01-31'
ele irá incluir de
2011-01-01 00:00:00
até2011-01-31 00:00:00
portanto, nada realmente em 2011-01-31 desde o seu tempo deve ir de2011-01-31 00:00:00 ~ 2011-01-31 23:59:59
Para o limite superior, você pode alterar para, em
2011-02-01
seguida, todos os dados serão atualizados2011-01-31 23:59:59
fonte