2017-11-14 1 views
1

Ich möchte eine Liste von Vierteln zwischen bestimmten Daten (StartDate und EndDate-Parameter) erhalten.Liste der Viertel zwischen zwei Daten (SQL)

Zum Beispiel Teil Quartal Daten:

StartDate : 2017-01-01 
EndDate : 2017-06-15 
Result : Q1 Q2 

eine weitere Probe:

StartDate : 2017-01-01 
EndDate : 2017-06-30 
Result : Q2 
+0

Können Sie bitte genauer erklären? wie nur Q2 im zweiten Beispiel? –

+0

ist es genaues Viertel. viertel 1: 2017-01-01 - 2017-31-03, viertel 2: 2017-04-01 2017-06-30 – NirNiroN

+0

Gibt es eine einzelne Zeichenfolge oder N Zeilen? –

Antwort

1

Sie so etwas wie dies versuchen könnte, müssten Sie die maximale Rekursion überschreiben, wenn Sie viele Viertel müssen Liste jedoch:

DECLARE @start_date DATE = '20170101'; 
DECLARE @end_date DATE = '20170615'; 
WITH x AS (
    SELECT 
     YEAR(@start_date) AS [year], 
     DATEPART(QUARTER, @start_date) AS [quarter] 
    UNION ALL 
    SELECT 
     CASE 
      WHEN [quarter] = 4 THEN [year] + 1 
      ELSE [year] 
     END AS [year], 
     CASE 
      WHEN [quarter] = 4 THEN 1 
      ELSE [quarter] + 1 
     END AS [quarter] 
    FROM 
     x 
    WHERE 
     [year] <= YEAR(@end_date) 
     AND [quarter] < DATEPART(QUARTER, @end_date)) 
SELECT * FROM x; 
+0

danke - gearbeitet. – NirNiroN

+0

Ich bekomme die gleiche Antwort, wenn ich entweder 20170615 oder 20170630 gebe. Andererseits macht die angeforderte Ausgabe von OP auch für mich keinen Sinn. – Zorkolot

+0

kann dies ohne das Schlüsselwort "With" erreicht werden? – NirNiroN

0

Wenn offen für einen TVF. Ich verwende oft eine Table-Valued-Funktion, um dynamische Datetime-Bereiche zurückzugeben.

Beispiel - Reihen

Select * 
     ,Qtr='Q'+DateName(QUARTER,RetVal) 
from [dbo].[tvf-Range-Date]('2017-01-01','2017-06-15','QQ',1) 

Returns

RetSeq RetVal  Qtr 
1  2017-01-01 Q1 
2  2017-04-01 Q2 

Beispiel - Einzelsaite

Select Qtr = Stuff((Select Distinct ' ' + 'Q'+DateName(QUARTER,RetVal) 
        From [dbo].[tvf-Range-Date]('2017-01-01','2017-06-15','QQ',1) 
        For XML Path ('')),1,1,'') 

Returns

Qtr 
Q1 Q2 

Die UDF, wenn Sie interessieren

CREATE FUNCTION [dbo].[tvf-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].[tvf-Range-Date]('2016-10-01','2020-10-01','YY',1) 
Select * from [dbo].[tvf-Range-Date]('2016-01-01','2017-01-01','MM',1) 
Select * from [dbo].[tvf-Range-Date]('2017-01-01','2017-01-02','MI',15) 
*/