Comment obtenir une table de dates entre x et y dans SQL Server 2005
-
01-07-2019 - |
Question
Je veux juste un moyen rapide (et de préférence ne pas utiliser de boucle while) de créer un tableau de toutes les dates comprises entre date @x et date @y afin que je puisse conserver la jointure externe à certaines tables de statistiques, dont certaines n'auront pas enregistrements pour certains jours entre les deux, me permettant de marquer les jours manquants avec un 0
La solution
À proprement parler, cela ne répond pas exactement à votre question, mais c’est plutôt bien.
En supposant que vous puissiez vivre en spécifiant le nombre de jours après la date de début, puis en utilisant une expression de table commune, vous obtiendrez:
WITH numbers ( n ) AS (
SELECT 1 UNION ALL
SELECT 1 + n FROM numbers WHERE n < 500 )
SELECT DATEADD(day,n-1,'2008/11/01') FROM numbers
OPTION ( MAXRECURSION 500 )
Autres conseils
Je crois que vous recherchez cet article de blog .
Je créerais une table d'agenda contenant uniquement toutes les dates d'une date de début appropriée à une date de fin appropriée. Cela ne prendrait pas beaucoup de place dans votre base de données et rendrait ce type de requête un jeu d'enfant.
select ...
from Calendar
left outer join
...
where Calendar.Date >= @x
and Calendar.Date <= @y
Je pense que vous pourriez aussi bien le faire en boucle. Je sais que c'est moche, mais c'est facile et ça marche.
En fait, je faisais quelque chose de similaire il y a quelque temps, mais je ne pouvais pas trouver un moyen de ne pas utiliser de boucle.
Le meilleur que j'ai obtenu était une table temporaire, puis la sélection des dates auxquelles je voulais me joindre.
Le blog sur lequel bduke est lié est mignon, bien que je pense que la solution de table temporaire est peut-être une solution plus propre.
J'ai trouvé une autre table qui stocke toutes les dates (ce sont les visiteurs du site Web), alors qu'en est-il de cela ...
Declare @FromDate datetime,
@ToDate datetime
Declare @tmpDates table
(StatsDate datetime)
Set @FromDate = DateAdd(day,-30,GetDate())
Set @ToDate = GetDate()
Insert Into @tmpDates (StatsDate)
Select
distinct CAST(FLOOR(CAST(visitDate AS DECIMAL(12, 5))) AS DATETIME)
FROM tbl_visitorstats
Where visitDate between @FromDate And @ToDate
Order By CAST(FLOOR(CAST(visitDate AS DECIMAL(12, 5))) AS DATETIME)
Select * FROM @tmpDates
Cela suppose que l'autre table ait une entrée pour chaque date que je veux, mais il est probable que 98% des données seront disponibles pour chaque jour.
Un léger changement dans la réponse donnée sous la forme https://stackoverflow.com/a/95728/395440 . Permet de spécifier les jours et calcule également la plage allant jusqu'à la date du jour.
DECLARE @startDate datetime
SET @startDate = '2015/5/29';
WITH number ( n ) AS (
SELECT 1 UNION ALL
SELECT 1 + n FROM dates WHERE n < DATEDIFF(Day, @startDate, GETDATE()) )
SELECT DATEADD(day,n-1,@startDate) FROM number where
datename(dw, DATEADD(day,n-1,@startDate)) in ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')
OPTION ( MAXRECURSION 500 )
Il suffit d'écrire la boucle. Quelqu'un doit écrire une boucle pour cela, que ce soit vous ou SQL Server.
DECLARE @Dates TABLE
(
TheDate datetime PRIMARY KEY
)
DECLARE @StartDate datetime, @EndDate datetime
SELECT @StartDate = '2000-01-01', @EndDate = '2010-01-01'
DECLARE @LoopVar int, @LoopEnd int
SELECT @LoopEnd = DateDiff(dd, @StartDate, @EndDate), @LoopVar = 0
WHILE @LoopVar <= @LoopEnd
BEGIN
INSERT INTO @Dates (TheDate)
SELECT DateAdd(dd,@LoopVar,@StartDate)
SET @LoopVar = @LoopVar + 1
END
SELECT *
FROM @Dates
Just: WHERE col > date de début ET col < date de fin