Consulta SQL para seleccionar fechas entre dos fechas

303

Tengo un start_datey end_date. Quiero obtener la lista de fechas entre estas dos fechas. ¿Alguien puede ayudarme a señalar el error en mi consulta?

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

Aquí Datehay una datetimevariable.

Neeraj
fuente

Respuestas:

484

deberías poner esas dos fechas entre comillas simples como ...

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

o puede usar

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

tenga en cuenta que la primera fecha es inclusiva, pero la segunda es exclusiva, ya que efectivamente es '2011/02/27 00:00:00'

Deepak
fuente
42
SQL Server predetermina una fecha sin hora a 00:00:00. Entonces, ¿esta consulta no devolverá nada del 25/02/2011 y 26/02/2011 a la medianoche?
Matt
55
@Deepak, tu segundo bit debería decir> = y <=
IndoKnight
3
Puede mencionar que el orden importa en la función ENTRE. Tiene que ir desde el más antiguo a la izquierda y más reciente a la derecha. Esto no es intuitivo ya que = es un operador comparativo en sql y funciona tanto para "EmployeeId = 1" como para "1 = EmployeeId" en la cláusula where.
Fi Horan
@Matt, de acuerdo con la documentación entre , si una fila tenía una fecha del 27/02/2011 sin una hora, entonces esa fila es equivalente a tener una fecha del 27/02/2011 00:00 y se devolvería en el consulta, porque es menor o igual que 2011/02/27 00:00. Entonces, si no está lidiando con el tiempo, betweendebería funcionar como se espera.
timctran
@timctran Correcto, pero el 27/02/2011 00:00 es lo que llamaríamos medianoche del 26/02/2011. Presumiblemente, la consulta significa incluir el número 27 en el conjunto de resultados, pero no se incluiría una entrada con una marca de tiempo del 27/02/2011 a las 5:00.
Sinjai
128

Dado que una fecha y hora sin un segmento de tiempo específico tendrá un valor de date 00:00:00.000, si desea asegurarse de obtener todas las fechas en su rango, debe proporcionar el tiempo para su fecha de finalización o aumentar su fecha de finalización y uso <.

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

O

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

O

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

NO use lo siguiente, ya que podría devolver algunos registros del 28/02/2011 si sus horarios son 00: 00: 00.000.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/28'
GalésDragón
fuente
42
La gente todavía mira estas preguntas y respuestas, incluso si originalmente se plantearon hace algún tiempo. Vine buscando una respuesta, y gran parte de lo que vi aquí era incompleto o absolutamente incorrecto. Mi respuesta no ayudará al póster original, pero podría ayudar a alguien, tal vez incluso dentro de tres años.
WelshDragon
3
Su respuesta me ayudó mucho, @WelshDragon: las otras respuestas omitieron el hecho de que el formato de fecha debe ser "fecha simple" en el servidor para ignorar las horas. "<= END_DATE" asume las 12AM, que no sabía. Estaba realizando una consulta con "... <= 01/01/2014" y no podía entender por qué los pedidos en esa fecha no se mostraban para el 1er. Muchas gracias.
Keith
@WelshDragon: su respuesta es un muy buen material para usar fechas como cláusula where. Gracias
Jack Frost
¿Qué pasa si vuelve '2011/02/28 00:00:00.000'?
Muflix
1
Intenté esto hoy, también podría usarlo convert(date, Date) between '2011/02/25' and '2011/02/27'(al menos con un servidor MS SQL reciente). La convert()parte se encargará de eliminar la parte del tiempo y la comparación entre ambos funcionará como se esperaba.
sensei
14

Prueba esto:

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

Los valores de fecha deben escribirse como cadenas.

Para garantizar que su consulta para SQL Server 2008 y Dateversiones posteriores esté preparada para el futuro, debe escaparse porque es una palabra reservada en versiones posteriores.

Tenga en cuenta que las fechas sin horario toman la medianoche como valores predeterminados, por lo que es posible que no tenga el valor correcto allí.


fuente
1
La fecha no es una palabra clave y no necesita escapar. El resaltado de sintaxis es solo el resaltado de sintaxis, las palabras clave solo deben escaparse si causan un error de sintaxis. También es una buena práctica usar la conversión explícita en lugar de la conversión implícita de constantes de cadena de fechas. - y Fecha entre CAST ('2011/02 / 25'AS DATETIME) y CAST (' 2011/02 / 27'AS DATETIME)
tponthieux
55
Naturalmente tiene razón si se trata de SQL Server 2005, que el OP etiquetó. Sin embargo, la fecha está reservada en 2008 y en adelante, por lo que para el futuro, no hay daño en escapar. He editado mi respuesta.
1
Si especificara la fecha única para ambos, devolvería cero filas, pero supongo que no es un requisito de
operación
12
select * from table_name where col_Date between '2011/02/25' 
AND DATEADD(s,-1,DATEADD(d,1,'2011/02/27'))

Aquí, primero agregue un día a la fecha final actual, será 2011-02-28 00:00:00, luego reste un segundo para hacer la fecha final 2011-02-27 23:59:59. Al hacer esto, puede obtener todas las fechas entre los intervalos dados.

output:
2011/02/25
2011/02/26
2011/02/27
Chandra Prakash
fuente
8
select * from test 
     where CAST(AddTime as datetime) between '2013/4/4' and '2014/4/4'

- si el tipo de datos es diferente

hamze shoae
fuente
5

Esta consulta es válida para recuperar los valores entre la fecha actual y sus próximas 3 fechas

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

Esto eventualmente agregará 3 días adicionales de búfer a la fecha actual.

Vinit Kadkol
fuente
5

Esto es muy antiguo, pero dada la gran cantidad de experiencias que he tenido con las fechas, es posible que desee considerar esto: las personas usan diferentes configuraciones regionales, como tal, algunas personas (y algunas bases de datos / computadoras, dependiendo de la configuración regional) pueden leer esto fecha 11/12/2016 como 11 de diciembre de 2016 o 12 de noviembre de 2016. Aún más, el 16/11/12 suministrado a la base de datos MySQL se convertirá internamente al 12 de noviembre de 2016, mientras que la base de datos de Access que se ejecuta en una computadora de configuración regional del Reino Unido interpretará y guárdelo como el 16 de noviembre de 2012.

Por lo tanto, hice que mi política sea explícita cada vez que voy a interactuar con fechas y bases de datos. Así que siempre proporciono mis consultas y códigos de programación de la siguiente manera:

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

Tenga en cuenta también que Access aceptará el #, por lo tanto:

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

pero el servidor MS SQL no lo hará, por lo que siempre uso "'" como se indicó anteriormente, que ambas bases de datos aceptan.

Y cuando obtengo esa fecha de una variable en el código, siempre convierto el resultado en una cadena de la siguiente manera:

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

Estoy escribiendo esto porque sé que a veces algunos programadores pueden no estar lo suficientemente interesados ​​en detectar la conversión inherente. No habrá errores para las fechas <13, ¡solo resultados diferentes!

En cuanto a la pregunta formulada, agregue un día a la última fecha y haga la comparación de la siguiente manera:

dated >= '11 Nov 2016' AND dated < '15 Nov 2016' 
Hannington Mambo
fuente
Su información ayudó a completar mi tarea. He trabajado en esto durante más de 10 horas y ninguna de las respuestas funcionaría para mí. Cuando me concateno como has demostrado, mi proyecto funciona muy bien. pero la regla parece ser no escribir una declaración SQL como esta. cada vez que intento configurar los SqlCommand para agregar los parámetros de fecha a la instrucción SQL, los parámetros no se adjuntarán y recibo el error de que debo declarar "@startDate" y "@endDate". No puedo pasar este problema. Probé su formato de fecha "dd MMM aaaa" que funcionó y también probé "aaaa MMM dd" que también realizó lo mismo.
Dave Hampel
¡Genial, ayudó! Arriba hay ejemplos de código. Siempre es mejor declarar y usar parámetros para evitar la inyección de SQL. Y parece que ya estás obligado / protegido por las reglas de tu proyecto, lo cual es bueno.
Hannington Mambo
4
select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and convert(varchar(10),Date,111) between '2011/02/25' and '2011/02/27'
njtd
fuente
3

Intente poner las fechas entre # #, por ejemplo:

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

Funcionó para mi.

Aleksandar
fuente
1
¿Qué hace # en este contexto?
BK
@BK es un delimitador, como comillas para cadenas. "Cuando se suministran valores a una instrucción SQL, por ejemplo, como criterio de consulta, su tipo de datos debe definirse correctamente mediante un" calificador ". Esto se realiza encerrando el valor entre un par de caracteres apropiados". referencia -> enlace
Aleksandar
1
@BK Si es una sintaxis TSql, deberá utilizar comillas simples ( ' ) para obtener lo que necesita. referencias * conceptos básicos de sql-fontstuff.com * SQL
Aleksandar
1
No podría estar más claro que la pregunta es para SQL Server y T-SQL. T-SQL y SQL Server no aceptan fechas entre etiquetas hash, acepta fechas entre comillas simples. Esta respuesta es incorrecta.
TT.
@TT. El número de votos positivos dice que todavía ayudó a alguien. Cuando escribí mi respuesta, la respuesta aceptada ya estaba elegida. Aún así, escribí esto para ayudar a cualquiera que pueda venir aquí desde Google o en otro lugar :)
Aleksandar
2

si su fecha en 24 horas y comienza en la mañana y termina en la noche debería agregar 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'
Sheryar Nizar
fuente
1

La mejor consulta para la fecha seleccionada entre la fecha actual y tres días atrás :

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

mejor consulta para la fecha seleccionada entre la fecha actual y los próximos tres días :

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

Verifique los siguientes ejemplos: tanto en funcionamiento como fuera de trabajo.

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

O

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

O

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

Y a continuación no funciona:

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**
Tobbin Well
fuente
1

podemos usar el medio para mostrar datos de dos fechas, pero esto buscará todos los datos y los comparará, por lo que nuestro proceso se ralentizará para obtener grandes datos, por lo que sugiero que todos usen datediff:

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

aquí el calendario es la Tabla, dt como la variable de fecha de inicio y dt2 es la variable de fecha de finalización.

Bipul Roy
fuente
0

Me gusta usar la sintaxis '1 MonthName 2015' para las fechas, por ejemplo:

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

para fechas

Juan
fuente
0

Yo iría por

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

La lógica es que >=incluye la fecha de inicio completa y <excluye la fecha de finalización, por lo que agregamos una unidad a la fecha de finalización. Esto puede adaptarse por meses, por ejemplo:

select Date, ... from ...
             where Date >= $start_month_day_1 and Date < DATEADD(m, 1, $end_month_day_1)
entonio
fuente
0
Select 
    * 
from 
    Calculation 
where 
    EmployeeId=1 and Date between #2011/02/25# and #2011/02/27#;
Saad Sheikh
fuente
0

Puedes probar este SQL

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

Realmente todas las fechas sql deben estar en formato aaaa-MM-dd para obtener los resultados más precisos.

Robert Peter Bronstein
fuente
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
Mojtaba Nava
fuente
-2

es mejor escribir de esta manera:

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
Hadi
fuente
1
El uso de un procedimiento almacenado en esta situación no tendrá ningún sentido, ya que reducirá horriblemente la flexibilidad de la consulta SQL, será muy específico.Si no desea usarlo en una situación realmente específica, no use un Procedimiento almacenado: también hay muchas mejoras disponibles para su Procedimiento almacenado que puede encontrar en esta comunidad;).
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');
Ankita
fuente
1
Probablemente estaba pensando en Oracle SQL cuando escribió esta respuesta. Esto es válido en Oracle. No tanto en SQL Server (por lo que puedo ver).
Charles Caldwell