2008-09-18 11 views
10

Po prostu chcę szybki sposób (a najlepiej nie używać pętli while) tworzenia tabeli każdej daty między datą @x a datą @y, więc można lewo sprzężenie zewnętrzne, aby niektóre statystyki tabel, z których niektóre nie będą miały zapisy na niektóre dni pomiędzy, pozwalając mi oznaczyć brakujące dni z 0Jak uzyskać tabelę dat między X i Y w serwerze sql 2005

Odpowiedz

18

Ściśle mówiąc, to nie odpowiada dokładnie na twoje pytanie, ale jest całkiem schludne.

Zakładając można żyć z określeniem liczby dni od daty rozpoczęcia, a następnie za pomocą wspólnego wyrażenia tabela przedstawia:

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) 
+0

Jesteś geniuszem! Dobra robota, nie myślałem o używaniu CTE! – digiguru

+0

Klauzula Opcja nie akceptuje zmiennej jako danych wejściowych, więc trzeba wiedzieć, ile dni w chwili pisania kodu. W przeciwnym razie: fajne rzeczy. –

+0

Ale jeśli chodzi o klauzulę Where, MAXRECURSION jest po prostu porażką, jeśli pętla idzie dalej. – digiguru

-4

sprawiedliwego: gdzie col> start-data i kol < end-date

+0

Próbuje utworzyć tabelę, aby wykonać lewe sprzężenie zewnętrzne. Nie zrobi tego, co chce. –

0

Myślę, że równie dobrze można to zrobić w pętli while. Wiem, że to brzydkie, ale to łatwe i działa.

0

Właściwie to robiłem coś podobnego, ale nie mogłem wymyślić sposobu, który nie użyłby pętli.

Najlepsze, co dostałem, to tabela tymczasowa, a następnie wybór dat, w których chciałem się przyłączyć.

Blog bduke z linkami jest ładny, chociaż myślę, że rozwiązanie z tabelą zastępczą jest prawdopodobnie czystszym rozwiązaniem.

0

Znalazłem inną tabelę, która przechowuje każdy dzień (to odwiedzający stronę), więc jak ten o ...

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 

To ma polegać na drugim stole o wpis na każdy dzień I chcesz, ale jest 98% prawdopodobne, że będą dane na każdy dzień.

-1

Wystarczy napisać pętlę. Ktoś musi napisać do tego pętlę, czy to ty - czy 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 
+0

Ludzie, którzy głosują bez komentowania ... lol. –

1

Chciałbym utworzyć tabelę Kalendarz że właśnie zawarte każdą datę z odpowiednią datą rozpoczęcia aż do odpowiedniej daty końcowej. Nie zajmowałoby to dużo miejsca w bazie danych i sprawiłoby, że tego typu zapytania byłyby dziecinnie proste.

select ... 
from Calendar 
     left outer join 
     ... 
where Calendar.Date >= @x 
and  Calendar.Date <= @y 
0

Nieznaczne skręcają na odpowiedź udzieloną jako https://stackoverflow.com/a/95728/395440. Pozwala na określenie dni, a także oblicza zakres do bieżącej daty.

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)