Consulta SQL para selecionar datas entre duas datas


303

Eu tenho um start_datee end_date. Quero obter a lista de datas entre essas duas datas. Alguém pode me ajudar a apontar o erro na minha consulta.

select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and Date between 2011/02/25 and 2011/02/27

Aqui Dateestá uma datetimevariável.

Respostas:


484

você deve colocar essas duas datas entre aspas simples como ..

select Date, TotalAllowance from Calculation where EmployeeId = 1
             and Date between '2011/02/25' and '2011/02/27'

ou pode usar

select Date, TotalAllowance from Calculation where EmployeeId = 1
             and Date >= '2011/02/25' and Date <= '2011/02/27'

lembre-se de que a primeira data é inclusiva, mas a segunda é exclusiva, pois é efetivamente '2011/02/27 00:00:00'


42
O SQL Server padroniza uma data sem hora para 00:00:00. Portanto, essa consulta não retornará nada de 25/02/2011 e 26/02/2011 à meia-noite?
21412 Matt

5
@Deepak, seu segundo bit deve dizer> = e <=
IndoKnight 26/06

3
Você pode mencionar que a ordem é importante na função BETWEEN. Tem que ir do mais antigo à esquerda e mais recente à direita. Isso não é intuitivo, pois = é um operador comparativo no sql e funciona para "EmployeeId = 1" ou "1 = EmployeeId" na cláusula where.
Fi Horan

@Matt, de acordo com a documentação entre , se uma linha tiver uma data de 27/02/2011 sem um horário, essa linha será equivalente a ter uma data de 27/02/2011 00:00 e seria retornada no consulta, porque é menor ou igual a 2011/02/27 00:00. Portanto, se você não está lidando com o tempo, betweendeve funcionar como esperado.
timctran

@timctran Certo, mas 27/02/2011 00:00 é o que chamaríamos de meia-noite de 26/02/2011. Presumivelmente, a consulta significa incluir o 27º no conjunto de resultados - mas uma entrada com um carimbo de data / hora de 27/02/2011 5:00 não seria incluída.
Sinjai

128

Como uma data e hora sem um segmento de tempo especificado terá um valor de date 00:00:00.000, se você quiser ter todas as datas em seu intervalo, deve fornecer a hora para a data final ou aumentar a data e o uso final <.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/27 23:59:59.999'

OU

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date >= '2011/02/25' and Date < '2011/02/28'

OU

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date >= '2011/02/25' and Date <= '2011/02/27 23:59:59.999'

NÃO use o seguinte, pois pode retornar alguns registros a partir de 28/02/2011 se o horário deles for 00: 00: 00.000.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/28'

42
As pessoas ainda olham para essas perguntas e respostas, mesmo que tenham sido colocadas originalmente há algum tempo. Eu vim procurando uma resposta, e muito do que vi aqui estava incompleto ou absolutamente incorreto. Minha resposta não vai ajudar o pôster original, mas pode ajudar alguém, talvez daqui a três anos.
WelshDragon

3
Sua resposta me ajudou muito, @WelshDragon - As outras respostas deixaram de fora o fato de que o formato da data precisa ser "data simples" no servidor para ignorar as horas. "<= END_DATE" assume 00:00, o que eu não sabia. Eu estava executando uma consulta com "... <= 01/01/2014" e não conseguia descobrir por que os pedidos naquela data não estavam sendo exibidos para o 1º. Muito obrigado.
Keith

@WelshDragon - sua resposta é um material muito bom para usar datas como cláusula where. Obrigado
Jack Frost

o que há de errado se voltar '2011/02/28 00:00:00.000'?
Muflix 14/02

1
Tentei isso hoje, você também pode usar convert(date, Date) between '2011/02/25' and '2011/02/27'(pelo menos com um MS SQL Server recente). A convert()peça cuidará da remoção da parte do tempo e a comparação entre as peças funcionará conforme o esperado.
sensei

14

Tente o seguinte:

select Date,TotalAllowance from Calculation where EmployeeId=1
             and [Date] between '2011/02/25' and '2011/02/27'

Os valores da data precisam ser digitados como seqüências de caracteres.

Para garantir que sua consulta para o SQL Server 2008 e superior Dateseja preparada para o futuro, ela deve ser escapada porque é uma palavra reservada em versões posteriores.

Lembre-se de que as datas sem horário são consideradas meia-noite como padrão; portanto, você pode não ter o valor correto lá.


1
Data não é uma palavra-chave e não precisa ser escapada. O realce da sintaxe é apenas o realce da sintaxe; as palavras-chave precisam ser escapadas apenas se causarem um erro de sintaxe. Também é uma boa prática usar a conversão explícita em vez da conversão implícita de constantes da cadeia de dados. - e Data entre o CAST ('2011/02 / 25'AS DATETIME) e o CAST (' '2011/02 / 27'AS DATETIME))
tponthieux

5
Naturalmente, você está certo se for o SQL Server 2005, que o OP marcou. No entanto, o Date é reservado a partir de 2008, portanto, para provas futuras, não há mal em escapar dele. Eu editei minha resposta.

1
Se ele iria especificar a data única para ambos seria retornar zero linhas, mas eu acho que não é a exigência de op
Zo Tem

12
select * from table_name where col_Date between '2011/02/25' 
AND DATEADD(s,-1,DATEADD(d,1,'2011/02/27'))

Aqui, primeiro adicione um dia à 2011-02-28 00:00:00data final atual, será , e você subtrairá um segundo para criar a data final 2011-02-27 23:59:59. Ao fazer isso, você pode obter todas as datas entre os intervalos especificados.

output:
2011/02/25
2011/02/26
2011/02/27

8
select * from test 
     where CAST(AddTime as datetime) between '2013/4/4' and '2014/4/4'

- se o tipo de dados for diferente


5

Essa consulta é boa para buscar os valores entre a data atual e as próximas 3 datas

SELECT * FROM tableName  WHERE columName 
BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)

Eventualmente, isso adicionará 3 dias extras de buffer à data atual.


5

Isso é muito antigo, mas, com muitas experiências que tive com datas, você pode considerar o seguinte: as pessoas usam configurações regionais diferentes; portanto, algumas pessoas (e alguns bancos de dados / computadores, dependendo das configurações regionais) podem ler isso 12/11/2016 como 11 de dezembro de 2016 ou 12 de novembro de 2016. Ainda mais, 16/11/12 fornecido ao banco de dados MySQL será convertido internamente para 12 de novembro de 2016, enquanto o banco de dados do Access executado em um computador de configuração regional do Reino Unido interpretará e armazená-lo como 16 de novembro de 2012.

Portanto, tornei minha política explícita sempre que vou interagir com datas e bancos de dados. Por isso, sempre forneço minhas consultas e códigos de programação da seguinte maneira:

SELECT FirstName FROM Students WHERE DoB >= '11 Dec 2016';

Observe também que o Access aceitará o #, assim:

SELECT FirstName FROM Students WHERE DoB >= #11 Dec 2016#;

mas o MS SQL Server não, então eu sempre uso "'" como acima, que ambos os bancos de dados aceitam.

E ao obter essa data de uma variável no código, eu sempre converto o resultado em string da seguinte maneira:

"SELECT FirstName FROM Students WHERE DoB >= " & myDate.ToString("d MMM yyyy")

Estou escrevendo isso porque sei que algumas vezes alguns programadores podem não estar interessados ​​o suficiente para detectar a conversão inerente. Não haverá erro para datas <13, apenas resultados diferentes!

Quanto à pergunta, adicione um dia à última data e faça a comparação da seguinte forma:

dated >= '11 Nov 2016' AND dated < '15 Nov 2016' 

suas informações ajudaram a concluir minha tarefa. Eu trabalhei nisso por mais de 10 horas e nenhuma das respostas funcionaria para mim. Quando concatenar como você mostrou, meu projeto funciona muito bem. mas a regra parece ser não escrever uma instrução SQL como esta. sempre que tento definir o SqlCommand para adicionar os parâmetros de data à instrução SQL, os parâmetros não serão anexados e recebo o erro que devo declarar "@startDate" e "@endDate". Não consigo passar esse problema. Eu tentei o seu formato de data "dd MMM aaaa", que funcionou e também tentei "aaaa MMM aaaa", que também executou o mesmo.
Dave Hampel 13/03

Ótimo, ajudou! Acima estão exemplos de código. É sempre melhor declarar e usar parâmetros para evitar a injeção de SQL. E parece que você já é requerido / protegido pelas regras do seu projeto, o que é bom.
Hannington Mambo 14/03

4
select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and convert(varchar(10),Date,111) between '2011/02/25' and '2011/02/27'

3

Tente colocar as datas entre # #, por exemplo:

#2013/4/4# and #2013/4/20#

Funcionou para mim.


1
O que # faz neste contexto?
BK

@BK é um delimitador, como aspas para strings. "Ao fornecer valores para uma instrução SQL, por exemplo, como critério de consulta, seu tipo de dados deve ser definido corretamente por um" qualificador ". Isso é feito colocando o valor entre um par de caracteres apropriados." referência -> link
Aleksandar

1
@BK Se for uma sintaxe TSql, você precisará usar aspas simples ( ' ) para obter o que precisa. referências * noções básicas de sql-fontstuff.com * Iniciando SQL - Paul Wilton, John Colby
Aleksandar

1
Não poderia ficar mais claro que a questão é para o SQL Server e o T-SQL. O T-SQL e o SQL Server não aceitam datas entre tags de hash, mas aceitam datas entre aspas simples. Esta resposta está errada.
TT.

@TT. o número de votos positivos diz que ainda ajudou alguém. No momento em que escrevi minha resposta, a resposta aceita já estava escolhida. Ainda assim, eu escrevi isso para ajudar qualquer pessoa que possa vir aqui do Google ou em outro lugar :)
Aleksandar

2

se a data em 24 horas e começar de manhã e terminar à noite, adicione algo como:

declare @Approval_date datetime
set @Approval_date =getdate()
Approval_date between @Approval_date +' 00:00:00.000' and @Approval_date +' 23:59:59.999'

1

melhor consulta para a data selecionada entre a data atual e os três dias anteriores :

  select Date,TotalAllowance from Calculation where EmployeeId=1 and Date BETWEEN       
DATE_SUB(CURDATE(), INTERVAL 3 DAY)  AND CURDATE() 

melhor consulta para a data selecionada entre a data atual e os próximos três dias :

  select Date,TotalAllowance from Calculation where EmployeeId=1 and Date BETWEEN   
   CURDATE()  AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)   

1

Confira abaixo Exemplos: Trabalhando e Não trabalhando.

select * from tblUser Where    
convert(varchar(10),CreatedDate,111) between '2015/04/01' and '2016/04/01' //--**Working**

OU

select * from tblUser Where
(CAST(CreatedDate AS DATETIME) between CAST('2015/04/01' AS DATETIME) And CAST('2016/4/30'AS DATETIME)) //--**Working**

OU

select * from tblUser Where
(YEAR(CreatedDate) between YEAR('2015/04/01') And YEAR('2016/4/30')) 
//--**Working**

E abaixo não está funcionando:

select * from tblUser Where
Convert(Varchar(10),CreatedDate,111) >=  Convert(Varchar(10),'01-01-2015',111) and  Convert(Varchar(10),CreatedDate,111) <= Convert(Varchar(10),'31-12-2015',111) //--**Not Working**


select * from tblUser Where
(Convert(Varchar(10),CreatedDate,111) between Convert(Varchar(10),'01-01-2015',111) And Convert(Varchar(10),'31-12-2015',111)) //--**Not Working**

1

podemos usar entre para mostrar dados de duas datas, mas isso pesquisará todos os dados e comparará, para tornar nosso processo lento para grandes dados, então sugiro que todos usem datediff:

qry = "SELECT * FROM [calender] WHERE datediff(day,'" & dt & "',[date])>=0 and datediff(day,'" & dt2 & "',[date])<=0 "

aqui o calendário é a tabela, dt como a variável da data de início e dt2 é a variável da data de término.


0

Eu gosto de usar a sintaxe '1 MonthName 2015' para datas ex:

   WHERE aa.AuditDate>='1 September 2015'
     AND aa.AuditDate<='30 September 2015'

para datas


0

Eu iria para

select Date,TotalAllowance from Calculation where EmployeeId=1
             and Date >= '2011/02/25' and Date < DATEADD(d, 1, '2011/02/27')

Como a lógica >=inclui toda a data de início e <exclui a data de término, adicionamos uma unidade à data de término. Isso pode ser adaptado por meses, por exemplo:

select Date, ... from ...
             where Date >= $start_month_day_1 and Date < DATEADD(m, 1, $end_month_day_1)

0
Select 
    * 
from 
    Calculation 
where 
    EmployeeId=1 and Date between #2011/02/25# and #2011/02/27#;

0

Você pode tentar este SQL

select * from employee where rec_date between '2017-09-01' and '2017-09-11' 


0
/****** Script for SelectTopNRows command from SSMS  ******/
SELECT TOP 10 [Id]
  ,[Id_parvandeh]
  ,[FirstName]
  ,[LastName]
  ,[RegDate]
  ,[Gilder]
  ,[Nationality]
  ,[Educ]
  ,[PhoneNumber]
  ,[DueInMashhad]

  ,[EzdevajDate]


  ,[MarriageStatus]
  ,[Gender]
  ,[Photo]

  ,[ModifiedOn]
  ,[CreatorIp]
   From
  [dbo].[Socials] where educ >= 3 or EzdevajDate  >= '1992/03/31' and EzdevajDate <= '2019/03/09' and MarriageStatus = 1

-2

é melhor escrever desta maneira:

CREATE PROCEDURE dbo.Get_Data_By_Dates
(
    @EmployeeId INT = 1,
    @Start_Date DATE,
    @End_Date Date
)
AS
Select * FROM Calculation  
    where EmployeeId=@EmployeeId AND Test_Date BETWEEN @Start_Date AND @End_Date
RETURN

1
O uso de um Procedimento Armazenado nessa situação não fará nenhum sentido, pois reduzirá drasticamente a flexibilidade da consulta SQL, será tão específico. Se você não quiser usá-lo em uma situação realmente específica, não use um Procedimento armazenado - Também existem muitas melhorias disponíveis para o seu Procedimento armazenado que você pode encontrá-los nesta comunidade;).
shA.t

-6
SELECT Date, TotalAllowance  
FROM Calculation  
WHERE EmployeeId = 1 
  AND Date BETWEEN to_date('2011/02/25','yyyy-mm-dd') 
               AND to_date ('2011/02/27','yyyy-mm-dd');

1
Você provavelmente estava pensando no Oracle SQL quando escreveu esta resposta. Isso é válido no Oracle. Não tanto no SQL Server (pelo que posso ver).
Charles Caldwell
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.