Obtenir des Dates entre plusieurs dates
j'ai besoin d'obtenir toutes les dates présentes dans la plage de dates à l'aide de SQL Server 2005
7 réponses
Ici, vous allez:
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);
si vous avez les dates dans une table et que vous voulez simplement sélectionner celles entre deux dates, vous pouvez utiliser
select * from yourTable where yourDate between date1 and date2
si vous voulez produire les dates à partir de rien, vous pouvez le faire avec une boucle ou vous pouvez remplir une table temporaire avec des dates et ensuite sélectionner à partir de cela.
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
un peu plus compliqué mais peut-être plus flexible serait d'utiliser une table contenant un ensemble séquentiel de nombres. Cela permet de plus d'une plage de dates avec des intervalles différents.
/* 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
j'utilise actuellementune variante de ceci pour diviser les dates en tranches de temps (avec divers intervalles, mais habituellement 5 minutes). Ma table @numbers contient un max de 288 car c'est le nombre total de 5 minutes de machines à sous que vous pouvez avoir dans une période de 24 heures.
/* 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
Voici la version Oracle de date generation:
SELECT TO_DATE ('01-OCT-2008') + ROWNUM - 1 g_date
FROM all_objects
WHERE ROWNUM <= 15
au lieu de all_objects il peut être n'importe quelle table avec assez de lignes pour couvrir la gamme.
si ce que vous voulez est d'obtenir toutes les dates présentes dans votre base de données entre deux dates (c.-à-d. quelles dates les clients ont passé des commandes au troisième trimestre de 2008) vous écririez quelque chose comme ceci:
select distinct(orderPlacedDate)
from orders
where orderPlacedDate between '2008-07-01' and 2008-09-30'
order by orderPlacedDate
Pour générer une plage de dates que vous pourriez écrire une fonction table. C'est une fonction qui crée une dimension de date pour un entrepôt de données - vous pouvez probablement s'adapter assez facilement par découper les promotions.
Edit: ici, il n'y a pas de hiérarchie des dimensions de date.
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