2014-11-27 14 views
7
declare @minDateTime as datetime; 
declare @maxDateTime as datetime; 

set @minDateTime = '2014-01-13 02:00:00'; 
set @maxDateTime = '2014-12-31 14:00:00'; 

szukam stworzyć select że wróci co godzinę między @minDateTime i @maxDateTime następująco (. Nie ma stół do wyboru ja nie szukam klauzuli WHERE!):Jak wybrać wszystkie godziny między dwiema datami?

2014-01-13 02:00:00 
2014-01-13 03:00:00 
2014-01-13 04:00:00 
... 
2014-12-31 12:00:00 
2014-12-31 13:00:00 
2014-12-31 14:00:00 
+0

więc jest to dobry powód, trzeba to zrobić w SQL zamiast C#? –

+0

Edytowałem twój tytuł. Zobacz, "[Czy w tytułach pytania powinny znaleźć się" znaczniki "?] (Http://meta.stackexchange.com/questions/19190/)", gdzie konsensus brzmi "nie, nie powinien". –

+0

@JohnSaunders Nauczyłem się znowu czegoś nowego. Dzięki;) – Marc

Odpowiedz

9

Spróbuj tego. Użyj Recursive CTE.

DECLARE @minDateTime AS DATETIME; 
DECLARE @maxDateTime AS DATETIME; 

SET @minDateTime = '2014-01-13 02:00:00'; 
SET @maxDateTime = '2014-12-31 14:00:00'; 

; 
WITH Dates_CTE 
    AS (SELECT @minDateTime AS Dates 
     UNION ALL 
     SELECT Dateadd(hh, 1, Dates) 
     FROM Dates_CTE 
     WHERE Dates < @maxDateTime) 
SELECT * 
FROM Dates_CTE 
OPTION (MAXRECURSION 0) 

W powyższym zapytania Dates_CTE jest Common Expression Table, płyta bazowa dla CTE pochodzi od pierwszego zapytania SQL przed UNION ALL. Wynik zapytania daje Minimum date.

Drugie zapytanie po UNION ALL jest wykonywane wielokrotnie, aby uzyskać wyniki. Ten proces jest recursive i będzie kontynuowany do daty mniejszej niż @maxDateTime.

+0

Witam. Mam następującą wiadomość: oświadczenie zostało wypowiedziane. Maksymalna rekurencja 100 została wyczerpana przed zakończeniem instrukcji. – Marc

+0

@Marc - Mój zły czek teraz –

+0

Awesome :) Dziękuję bardzo! – Marc

2

Oto inny sposób za pomocą Tally Table:

DECLARE @minDateTime DATETIME; 
DECLARE @maxDateTime DATETIME; 

SET @minDateTime = '2014-01-13 02:00:00'; 
SET @maxDateTime = '2014-12-31 14:00:00'; 

DECLARE @hrsDiff INT; 
SELECT @hrsDiff = DATEDIFF(HH, @minDateTime, @maxDateTime); 

WITH E1(N) AS (
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
),--10E+1 or 10 rows 
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows 
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max 
Tally(N) AS(SELECT row_number() over(order by (select null)) from E4) -- Numbered rrow 
SELECT @minDateTime 
UNION ALL 
SELECT DATEADD(HH, N, @minDateTime) 
FROM Tally 
WHERE 
    N <= @hrsDiff 
Powiązane problemy