2011-01-19 16 views
6

Mam tabelę danych, które chcę wybrać za pośrednictwem przechowywanego procesu, tak aby użytkownicy mogli podłączyć do niego MS Excel i używać surowych danych jako źródła do wykresu.wygenerować tabelę sql temp kolejnych dat na lewe sprzężenie zewnętrzne do

Problem z surowymi danymi tabeli istnieje istnieją luki w datach, ponieważ jeśli nie ma danych dla danego dnia (nie ma zapisów z tą datą), wtedy, gdy użytkownicy próbują go wykreślić, stwarza problemy.

Chcę też zaktualizować mój zapisany proces do lewego zewnętrznego sprzężenia do tabeli tymczasowych dat, tak aby prawa strona pojawiła się jako wartości null, które mogę odrzucić do zera, aby miały proste doświadczenie w kreśleniu.

Jak najlepiej wygenerować jedną tabelę pól dat między datą początkową a końcową?

+0

Szukacie generatora sekwencji; [this] (http://msdn.microsoft.com/en-us/library/aa175802 (v = sql.80) .aspx) był artykułem, który oparłem na moim ostatnim razie, kiedy go potrzebowałem. Chociaż, oczywiście, jeśli chcesz zrobić to tylko raz, kursor lub prosta pętla będzie dobrze ... –

Odpowiedz

12

W SQL Server 2005 iw górę, można użyć coś takiego (a Common Expression tabeli CTE), aby to zrobić:

DECLARE @DateFrom DATETIME 
SET @DateFrom = '2011-01-01' 

DECLARE @DateTo DATETIME 
SET @DateTo = '2011-01-10' 

;WITH DateRanges AS 
(
    SELECT @DateFrom AS 'DateValue' 
    UNION ALL 
    SELECT DATEADD(DAY, 1, DateValue) 
    FROM DateRanges 
    WHERE DateValue < @DateTo 
) 
SELECT * FROM DateRanges 

Mogłeś LEFT OUTER JOIN to CTE na stole i zwraca wynik.

+0

Wreszcie! Dziękuję Ci za to. Wydawało się, że powinno być tak proste, a jednak wszystkie inne odpowiedzi na bardzo podobne pytania dotyczyły tworzenia funkcji lub stałych tabel. To jest dokładnie to, czego potrzebowałem i działa idealnie. –

+0

To jest łatwiejszy sposób, ale jeśli rośnie do tysięcy lub milionów dat, ma słabą wydajność w porównaniu do tabeli tymczasowej lub stałej. Sprawdź to: http://www.sqlservercentral.com/articles/T-SQL/74118/ –

4

Jednym ze sposobów byłoby z CTE:

with cte_dates as (
    select cast('20110119' as datetime) as [date] 
    union all 
    select dateadd(dd, 1, [date]) 
     from cte_dates 
     where dateadd(dd, 1, [date]) <= '20111231' 
) 
select [date], YourColumn 
    from cte_dates 
     left join YourTable 
      on ... 
option (maxrecursion 0); 
+0

+1, ponieważ Twój wpis został przesłany dokładnie w chwili zatwierdzonej odpowiedzi, a ponieważ twoja klauzula WHERE jest bardziej niezawodna niż jego (działa dla interwałów większych niż 1, co jest przeoczane w zaakceptowanej odpowiedzi). – kmote

4

Innym sposobem na to jest ze stołem pamięci. Nie będzie się dusić z powodu ograniczeń rekursji, takich jak niektóre z powyższych rozwiązań.

DECLARE @dates AS TABLE ([Date] date); 

DECLARE @date date = {d '2010-10-01'}; 
DECLARE @endDate date = {d '2010-11-01'}; 

while (@date < @endDate) 
BEGIN 
    INSERT INTO @dates VALUES (@date); 
    SET @date = dateadd(DAY, 1, @date) 
END 
SELECT * FROM @dates; 

SQL Fiddle

+0

Użyj tego rozwiązania, jeśli otrzymasz komunikat "Maksymalna rekurencja została wyczerpana." – Diego

Powiązane problemy