2016-11-30 4 views
0

Ich versuche, die Start-und Enddaten jeder Woche für einen bestimmten Zeitraum zu bekommen. Zum Beispiel den DatumsbereichWie bekomme ich das Start-und Enddatum jeder Woche in einem bestimmten Zeitraum in SQL Server

BETWEEN '11-21-2016' AND '12-25-2016' 

Ich brauche angesichts der folgenden Start- und Enddaten zu erhalten:

'11-21-2016' AND '11-27-2016' 
'11-28-2016' AND '12-04-2016' 
'12-05-2016' AND '12-11-2016' 
'12-12-2016' AND '12-18-2016' 
'12-19-2016' AND '12-25-2016' 

ich hier ein paar Beispiele gefunden im Monat Namen gegeben, wenn beispielsweise Dezember gegeben wird es tun Sie, wie oben für diesen Monat erklärt. Sie können jedoch keine Beispiele finden, die einen Datumsbereich als Anfangsmonat verwenden.

+1

, was passiert, wenn mit ''11 Bereichsanfang -23- 2016''? Ihre Woche beginnt immer noch um 21? –

+0

@JuanCarlosOropeza. Ist das ein gültiges Datum? –

+0

BTW, deshalb sollten Sie immer Datum als ansi-Standard 'JJJJ-MM-TT' posten, um diese Fehler zu vermeiden –

Antwort

0

eine Zahlen-Tabelle verwenden, definieren Anfang und Ende, finden die Termine zwischen (My MSSQL rostig ist, können Sie Syntax beheben) eine TVF

declare @STARTDATE date; 
declare @ENDDATE date; 
set @STARTDATE = '2016-21-11'; 
set @ENDDATE = '2016-12-25'; 

with Nums as 
(
select 1 as NN 
union all 
select NN+1 as NN 
fom Nums 
where NN < 1000 
) 
select dateadd(dd, NN, @STARTDATE) as DayStart, dateadd(dd, NN+6, @STARTDATE) as DayEnd 
from Nums 
where dateadd(dd, NN+6, @STARTDATE) <= @ENDDATE 
and datepart(dw,dateadd(dd, NN, @STARTDATE))=1 
+1

Du musst ein '' 'nach der vorhergehenden Zeile einfügen. Oft gesehen: '; WITH', um dies zu vermeiden ... – Shnugo

+0

@JohnHC müssen Sie immer noch Ihre früheren Aussagen (Ihre' set' Anweisungen) vor der CTE beenden. Hast du versucht, das auszuführen? 'Erklären @StartDate Datetime Satz @StartDate = getdate MIT CTE AS (SELECT 1 als) SELECT * FROM CTE' – scsimon

+0

Danke Jungs, total vergessen darüber. – JohnHC

1

ich oft verwenden dynamische Datums-/Zeitbereiche zu erstellen. I tally table würde auch den Trick machen. Das heißt, die UDF ist schneller als ein rekursiver Ansatz für größere Mengen und bietet ein bisschen mehr Funktionalität. Zum Beispiel definieren Sie den Datumsbereich, Datumsteil und erhöhen

Select DateR1=RetVal,DateR2=DateAdd(DD,6,RetVal) from [dbo].[udf-Range-Date]('2016-11-21','2016-12-25','DD',7) 

Returns

DateR1  DateR2 
2016-11-21 2016-11-27 
2016-11-28 2016-12-04 
2016-12-05 2016-12-11 
2016-12-12 2016-12-18 
2016-12-19 2016-12-25 

Die UDF, wenn gewünscht

CREATE FUNCTION [dbo].[udf-Range-Date] (@R1 datetime,@R2 datetime,@Part varchar(10),@Incr int) 
Returns Table 
Return (
    with cte0(M) As (Select 1+Case @Part When 'YY' then DateDiff(YY,@R1,@R2)/@Incr When 'QQ' then DateDiff(QQ,@R1,@R2)/@Incr When 'MM' then DateDiff(MM,@R1,@R2)/@Incr When 'WK' then DateDiff(WK,@R1,@R2)/@Incr When 'DD' then DateDiff(DD,@R1,@R2)/@Incr When 'HH' then DateDiff(HH,@R1,@R2)/@Incr When 'MI' then DateDiff(MI,@R1,@R2)/@Incr When 'SS' then DateDiff(SS,@R1,@R2)/@Incr End), 
     cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)), 
     cte2(N) As (Select Top (Select M from cte0) Row_Number() over (Order By (Select NULL)) From cte1 a, cte1 b, cte1 c, cte1 d, cte1 e, cte1 f, cte1 g, cte1 h), 
     cte3(N,D) As (Select 0,@R1 Union All Select N,Case @Part When 'YY' then DateAdd(YY, N*@Incr, @R1) When 'QQ' then DateAdd(QQ, N*@Incr, @R1) When 'MM' then DateAdd(MM, N*@Incr, @R1) When 'WK' then DateAdd(WK, N*@Incr, @R1) When 'DD' then DateAdd(DD, N*@Incr, @R1) When 'HH' then DateAdd(HH, N*@Incr, @R1) When 'MI' then DateAdd(MI, N*@Incr, @R1) When 'SS' then DateAdd(SS, N*@Incr, @R1) End From cte2) 

    Select RetSeq = N+1 
      ,RetVal = D 
    From cte3,cte0 
    Where D<[email protected] 
) 
/* 
Max 100 million observations -- Date Parts YY QQ MM WK DD HH MI SS 
Syntax: 
Select * from [dbo].[udf-Range-Date]('2016-10-01','2020-10-01','YY',1) 
Select * from [dbo].[udf-Range-Date]('2016-01-01','2017-01-01','MM',1) 
*/ 
Verwandte Themen