2008-11-07 18 views
15

muszę uzyskać wszystkie daty występujące w przedziale czasowym za pomocą SQL Server 2005Getting dniach między zakresu dat

+0

Chcesz generować daty, lub po prostu poszukać istniejącego pola? – Unsliced

+3

Harish, proszę zaznaczyć jedną z odpowiedzi poniżej jako odpowiedź. Potrzebowali czasu, aby ci pomóc. – FMFF

Odpowiedz

8

Jeśli masz daty w tabeli i po prostu chcą, aby wybrać te, między dwiema datami można użyć

select * from yourTable where yourDate between date1 and date2 

Jeśli chcesz produkować daty z niczego można zrobić z pętli lub można wypełnić tabelę tymczasową z datami, a następnie wybrać z tego.

-3

Aby wygenerować zakres dat, można napisać funkcję z wartościami przechowywanymi w tabeli. Jest to funkcja, która tworzy wymiar daty dla hurtowni danych - prawdopodobnie można ją łatwo dostosować poprzez przycinanie znaków specjalnych.

Edytuj: Tutaj jest bez hierarchii wymiarów daty.

if object_id ('ods.uf_DateHierarchy') is not null 
    drop function ods.uf_DateHierarchy 
go 

create function ods.uf_DateHierarchy (
     @DateFrom datetime 
     ,@DateTo datetime 
) returns @DateHierarchy table (
     DateKey   datetime 
) as begin 
    declare @today   datetime 
    set @today = @Datefrom 

    while @today <= @DateTo begin 
     insert @DateHierarchy (DateKey) values (@today) 
     set @today = dateadd (dd, 1, @today) 
    end 

    return 
end 

go 
57

Proszę bardzo:

DECLARE @DateFrom smalldatetime, @DateTo smalldatetime; 
SET @DateFrom='20000101'; 
SET @DateTo='20081231'; 
------------------------------- 
WITH T(date) 
AS 
( 
SELECT @DateFrom 
UNION ALL 
SELECT DateAdd(day,1,T.date) FROM T WHERE T.date < @DateTo 
) 
SELECT date FROM T OPTION (MAXRECURSION 32767); 
+0

Przeszukuję to rozwiązanie. Zastosuj coś podobnego w przypadku osi czasu, więc wykresy zachowują spójny interwał nawet bez pasujących rekordów dla tego okresu w bazie danych. –

+1

Dobrze. Działa to w celu wygenerowania dowolnych sekwencji: wystarczy zastąpić DateAdd (dzień, 1, T.date) inną formułą this_item = F (previous_item) – Incidently

+0

Bardzo fajne rozwiązanie w/CTE. Nie widziałem tego wcześniej. – jons911

-2

Jeśli to, co chcesz, aby wszystkie dat znajdujących się w bazie danych między dwiema datami (tj jakie terminy są klienci umieszczone zamówień w Q3 2008) byś napisać coś takiego:

select distinct(orderPlacedDate) 
from orders 
where orderPlacedDate between '2008-07-01' and 2008-09-30' 
order by orderPlacedDate 
0

Oto Oracle wersja generacji data:

SELECT TO_DATE ('01-OCT-2008') + ROWNUM - 1 g_date 
    FROM all_objects 
WHERE ROWNUM <= 15 

zamiast all_objects może to być dowolna tabela z wystarczającą liczbą rzędów, aby pokryć wymagany zakres.

1

Nieco bardziej skomplikowana, ale być może bardziej elastyczna byłaby możliwość skorzystania z tabeli zawierającej sekwencyjny zestaw liczb. Pozwala to na więcej niż jeden zakres dat z różnymi interwałami.

/* holds a sequential set of number ie 0 to max */ 
/* where max is the total number of rows expected */ 
declare @Numbers table (Number int ) 

declare @max int 
declare @cnt int 

set @cnt = 0 
/* this value could be limited if you knew the total rows expected */ 
set @max = 999 

/* we are building the NUMBERS table on the fly */ 
/* but this could be a proper table in the database */ 
/* created at the point of first deployment */ 
while (@cnt <= @max) 
begin 
     insert into @Numbers select @cnt 
     set @cnt = @cnt + 1 
end 

/* EXAMPLE of creating dates with different intervals */ 

declare @DateRanges table ( 
    StartDateTime datetime, EndDateTime datetime, Interval int) 

/* example set of date ranges */ 
insert into @DateRanges 
select '01 Jan 2009', '10 Jan 2009', 1 /* 1 day interval */ 
union select '01 Feb 2009', '10 Feb 2009', 2 /* 2 day interval */ 

/* heres the important bit generate the dates */ 
select 
     StartDateTime 
from 
(
     select 
      d.StartDateTime as RangeStart, 
      d.EndDateTime as RangeEnd, 
      dateadd(DAY, d.Interval * n.Number, d.StartDateTime) as StartDateTime 
     from 
      @DateRanges d, @Numbers n 
) as dates 
where 
     StartDateTime between RangeStart and RangeEnd 
order by StartDateTime 

I actully stosować odmianę tego podziału dat na szczeliny czasowe (z różnych odstępach czasu, ale długo zazwyczaj 5 minut). Moja tabela @numbers zawiera maksymalnie 288, ponieważ jest to całkowita liczba 5-minutowych slotów, które możesz mieć w ciągu 24 godzin.

/* EXAMPLE of creating times with different intervals */ 

delete from @DateRanges 

/* example set of date ranges */ 
insert into @DateRanges 
select '01 Jan 2009 09:00:00', '01 Jan 2009 12:00:00', 30 /* 30 minutes interval */ 
union select '02 Feb 2009 09:00:00', '02 Feb 2009 10:00:00', 5 /* 5 minutes interval */ 

/* heres the import bit generate the times */ 
select 
     StartDateTime, 
     EndDateTime 
from 
(
     select 
      d.StartDateTime as RangeStart, 
      d.EndDateTime as RangeEnd, 
      dateadd(MINUTE, d.Interval * n.Number, d.StartDateTime) as StartDateTime, 
      dateadd(MINUTE, d.Interval * (n.Number + 1) , StartDateTime) as EndDateTime 
     from 
      @DateRanges d, @Numbers n 
) as dates 
where 
     StartDateTime >= RangeStart and EndDateTime <= RangeEnd 
order by StartDateTime 
4
DECLARE @Date1 DATE='2016-12-21', @Date2 DATE='2016-12-25' 
SELECT DATEADD(DAY,number,@Date1) [Date] FROM master..spt_values WHERE type = 'P' AND DATEADD(DAY,number,@Date1) <= @Date2 
Powiązane problemy