sql - por - Obtener fechas entre un rango de fechas
obtener un rango de fechas en sql (7)
DECLARE @Date1 DATE=''2016-12-21'', @Date2 DATE=''2016-12-25''
SELECT DATEADD(DAY,number,@Date1) [Date] FROM master..spt_values WHERE type = ''P'' AND DATEADD(DAY,number,@Date1) <= @Date2
Necesito obtener todas las fechas presentes en el rango de fechas usando SQL Server 2005
Aquí está la versión de generación de fechas de Oracle:
SELECT TO_DATE (''01-OCT-2008'') + ROWNUM - 1 g_date
FROM all_objects
WHERE ROWNUM <= 15
en lugar de all_objects, puede ser cualquier tabla con suficientes filas para cubrir el rango requerido.
Aqui tienes:
DECLARE @DateFrom smalldatetime, @DateTo smalldatetime;
SET @DateFrom=''20000101'';
SET @DateTo=''20081231'';
-------------------------------
WITH T(date)
AS
(
SELECT @DateFrom
UNION ALL
SELECT DateAdd(day,1,T.date) FROM T WHERE T.date < @DateTo
)
SELECT date FROM T OPTION (MAXRECURSION 32767);
Para generar un rango de fechas, puede escribir una función con valores de tabla. Esta es una función que crea una dimensión de fecha para un depósito de datos: probablemente podría adaptarla con bastante facilidad recortando las ofertas especiales.
Editar: Aquí está sin la jerarquía de dimensión de fecha.
if object_id (''ods.uf_DateHierarchy'') is not null
drop function ods.uf_DateHierarchy
go
create function ods.uf_DateHierarchy (
@DateFrom datetime
,@DateTo datetime
) returns @DateHierarchy table (
DateKey datetime
) as begin
declare @today datetime
set @today = @Datefrom
while @today <= @DateTo begin
insert @DateHierarchy (DateKey) values (@today)
set @today = dateadd (dd, 1, @today)
end
return
end
go
Si tiene las fechas en una tabla y simplemente desea seleccionar aquellas entre dos fechas, puede usar
select * from yourTable where yourDate between date1 and date2
Si desea generar las fechas a partir de nada, puede hacerlo con un bucle o puede completar una tabla temporal con fechas y luego seleccionar desde allí.
Un poco más complicado pero quizás más flexible sería hacer uso de una tabla que contiene un conjunto secuencial de números. Esto permite más de un rango de fechas con diferentes intervalos.
/* holds a sequential set of number ie 0 to max */
/* where max is the total number of rows expected */
declare @Numbers table ( Number int )
declare @max int
declare @cnt int
set @cnt = 0
/* this value could be limited if you knew the total rows expected */
set @max = 999
/* we are building the NUMBERS table on the fly */
/* but this could be a proper table in the database */
/* created at the point of first deployment */
while (@cnt <= @max)
begin
insert into @Numbers select @cnt
set @cnt = @cnt + 1
end
/* EXAMPLE of creating dates with different intervals */
declare @DateRanges table (
StartDateTime datetime, EndDateTime datetime, Interval int )
/* example set of date ranges */
insert into @DateRanges
select ''01 Jan 2009'', ''10 Jan 2009'', 1 /* 1 day interval */
union select ''01 Feb 2009'', ''10 Feb 2009'', 2 /* 2 day interval */
/* heres the important bit generate the dates */
select
StartDateTime
from
(
select
d.StartDateTime as RangeStart,
d.EndDateTime as RangeEnd,
dateadd(DAY, d.Interval * n.Number, d.StartDateTime) as StartDateTime
from
@DateRanges d, @Numbers n
) as dates
where
StartDateTime between RangeStart and RangeEnd
order by StartDateTime
De hecho, utilizo una variación de esto para dividir las fechas en intervalos de tiempo (con varios intervalos, pero generalmente de 5 minutos de duración). Mi tabla @numbers contiene un máximo de 288 ya que esa es la cantidad total de tragamonedas de 5 minutos que puede tener en un período de 24 horas.
/* EXAMPLE of creating times with different intervals */
delete from @DateRanges
/* example set of date ranges */
insert into @DateRanges
select ''01 Jan 2009 09:00:00'', ''01 Jan 2009 12:00:00'', 30 /* 30 minutes interval */
union select ''02 Feb 2009 09:00:00'', ''02 Feb 2009 10:00:00'', 5 /* 5 minutes interval */
/* heres the import bit generate the times */
select
StartDateTime,
EndDateTime
from
(
select
d.StartDateTime as RangeStart,
d.EndDateTime as RangeEnd,
dateadd(MINUTE, d.Interval * n.Number, d.StartDateTime) as StartDateTime,
dateadd(MINUTE, d.Interval * (n.Number + 1) , StartDateTime) as EndDateTime
from
@DateRanges d, @Numbers n
) as dates
where
StartDateTime >= RangeStart and EndDateTime <= RangeEnd
order by StartDateTime
Si lo que quiere es tener todas las fechas presentes en su base de datos entre dos fechas (es decir, las fechas en que los clientes hicieron los pedidos en el tercer trimestre de 2008), debería escribir algo como esto:
select distinct(orderPlacedDate)
from orders
where orderPlacedDate between ''2008-07-01'' and 2008-09-30''
order by orderPlacedDate