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

Était-ce utile?

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top