答案:(SQL)(TSQL)从日期范围确定期间

时间:2014-09-17 21:39:30

标签: sql common-table-expression period

使用@ReportingEndingDate,请及时(@NumberOfPeriods

1)将采用开始和结束日期范围 2)将执行不同的期间':季度,月份或年份 3)会做' x'期数 4)可以从开始日期开始并前进到结束    日期或从结束日期开始,然后返回到开始日期    日期。前者显然是经常使用的,但后者是    用于您想要选择结束日期并向后退的情况    ' X'期数。

有些情况: 1)

DECLARE @Start DATETIME = '2013-01-01 00:00:00'
        ,@End DATETIME = '2014-08-15 23:59:59'
        ,@Period TINYINT = 1 -- 1 = Quarter, 2 = Month, 3 = Year
        ,@NumerOfPeriods SMALLINT = 24
        ,@StartingDateIsOrigniationDate BIT = 1

    SELECT * FROM udf_SplitDateRangeIntoPeriods(@Start, @End, @Period, @NumerOfPeriods, @StartingDateIsOrigniationDate)

1/1/2013 12:00:00 AM 3/31/2013 11:59:59 PM 4/1/2013 12:00:00 AM 6/30/2013 11:59:59 PM 2013年7月1日12:00:00 AM 9/30/2013 11:59:59 PM 10/1/2013 12:00:00 AM 12/31/2013 11:59:59 PM 1/1/2014 12:00:00 AM 3/31/2014 11:59:59 PM 4/1/2014 12:00:00 AM 6/30/2014 11:59:59 PM - 不再是最后的部分时期

2)

DECLARE @Start DATETIME = '2013-01-01 00:00:00'
        ,@End DATETIME = '2014-08-15 23:59:59'
        ,@Period TINYINT = 1 -- 1 = Quarter, 2 = Month, 3 = Year
        ,@NumerOfPeriods SMALLINT = 24
        ,@StartingDateIsOrigniationDate BIT = 0
SELECT * FROM udf_SplitDateRangeIntoPeriods(@Start, @End, @Period, @NumerOfPeriods, @StartingDateIsOrigniationDate)

6/1/2014 12:00:00 AM 8/15/2014 11:59:59 PM - 部分期间 3/1/2014 12:00:00 AM 5/31/2014 11:59:59 PM 12/1/2013 12:00:00 AM 2/28/2014 11:59:59 PM 2013年9月1日12:00:00 AM 11/30/2013 11:59:59 PM 6/1/2013 12:00:00 AM 8/31/2013 11:59:59 PM 3/1/2013 12:00:00 AM 5/31/2013 11:59:59 PM

/*
-- =============================================
   Author:          Daniel Kram
   Create date:   September 2014
   Description:   Returns a table with a date range
   Modifications:

   Example:

-- =============================================

*/

IF EXISTS (SELECT name
           FROM
             sysobjects
           WHERE
             name = 'udf_SplitDateRangeIntoPeriods'
             AND type = 'TF'
          )
  DROP FUNCTION dbo.udf_SplitDateRangeIntoPeriods;
GO

SET QUOTED_IDENTIFIER, ANSI_NULLS ON
GO

CREATE FUNCTION dbo.udf_SplitDateRangeIntoPeriods
(
  @StartingDate DATETIME,
  @EndingDate   DATETIME,
  @PeriodType TINYINT = 0,            -- 0 = use date-range only, 1 = quarter, 2 = month, 3 = year
  @NumberOfPeriods SMALLINT = NULL,
  @StartingDateIsFocus BIT = 1        -- 1 = Starting date is the origination point, 0 = ending date is the orignation point
)
RETURNS @DateResults TABLE 
  (FromDate DATETIME
  ,ToDate DATETIME
  ,MyRowNumber INT)
  AS BEGIN

    IF (@NumberOfPeriods IS NULL) OR (@NumberOfPeriods = 0)
      SET @NumberOfPeriods = 99;

    IF (@PeriodType = 0)
    BEGIN
      INSERT INTO @DateResults (FromDate, ToDate, MyRowNumber) SELECT @StartingDate, @EndingDate, 1
    END
    -- Quarters, working backwards from ending date
    ELSE IF (@PeriodType = 1)
    BEGIN
      IF (@StartingDateIsFocus = 1)
      BEGIN
        WITH Quarters AS
        (
            SELECT @StartingDate AS 'FromDate'
              ,DATEADD(ss,-1,DATEADD(mm, DATEDIFF(m,0,@StartingDate)+3,0)) as 'ToDate'
              ,1 AS MyRowNumber
            UNION ALL
            SELECT CAST(DATEADD(d, 1, EOMONTH(ToDate)) AS DATETIME) AS 'FromDate'
              ,DATEADD(ss,-1,DATEADD(dd,1,CAST(EOMONTH(DATEADD(MONTH,3,ToDate)) AS DATETIME))) as 'ToDate'
              ,MyRowNumber + 1 AS MyRowNumber
            FROM Quarters
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND MyRowNumber < 99
        ) INSERT INTO @DateResults (FromDate, ToDate, MyRowNumber) SELECT * FROM Quarters
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
      END
      ELSE IF (@StartingDateIsFocus = 0)
      BEGIN
        WITH Quarters AS
        (
            SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, DATEADD(MONTH,-2,DATEADD(day, -DATEPART(day, @EndingDate)+1, @EndingDate))), 0) as 'FromDate'
              ,@EndingDate AS 'ToDate'
              ,1 AS MyRowNumber
            UNION ALL
            SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, DATEADD(MONTH,-3,DATEADD(day, -DATEPART(day, FromDate)+1, FromDate))), 0) as 'FromDate'
              ,DATEADD(ss,-1,DATEADD(mm, DATEDIFF(m,0,DATEADD(MONTH, -3, ToDate))+1,0)) AS 'ToDate'
              ,MyRowNumber + 1 AS MyRowNumber
            FROM Quarters
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
        ) INSERT INTO @DateResults (FromDate, ToDate, MyRowNumber) SELECT * FROM Quarters 
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
      END
    END
    ELSE IF (@PeriodType = 2)
    BEGIN
      IF (@StartingDateIsFocus = 1)
      BEGIN
        WITH YearPeriod AS
        (
            SELECT @StartingDate AS 'FromDate'
              ,DATEADD(ss,-1,DATEADD(MONTH,1,@StartingDate)) as 'ToDate'
              ,1 AS MyRowNumber
            UNION ALL
            SELECT DATEADD(ss,1,ToDate) as 'FromDate'
              ,DATEADD(ss,-1,DATEADD(mm, DATEDIFF(m,0,ToDate)+2,0)) as 'ToDate'
              ,MyRowNumber + 1 AS MyRowNumber
            FROM YearPeriod
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
        ) INSERT INTO @DateResults (FromDate, ToDate, MyRowNumber) SELECT * FROM YearPeriod
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
      END
      ELSE IF (@StartingDateIsFocus = 0)
      BEGIN
        WITH YearPeriod AS
        (
            SELECT DATEADD(ss,1,DATEADD(MONTH,-1,@EndingDate)) as 'FromDate'
              ,@EndingDate AS 'ToDate'
              ,1 AS MyRowNumber
            UNION ALL
            SELECT DATEADD(ss,1,DATEADD(MONTH,-1,FromDate)) as 'FromDate'
              ,DATEADD(MONTH,-1,ToDate) as 'ToDate'
              ,MyRowNumber + 1 AS MyRowNumber
            FROM YearPeriod
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
        ) INSERT INTO @DateResults (FromDate, ToDate, MyRowNumber) SELECT * FROM YearPeriod
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
      END
    END
    ELSE IF (@PeriodType = 3)
    BEGIN
      IF (@StartingDateIsFocus = 1)
      BEGIN
        WITH YearPeriod AS
        (
            SELECT @StartingDate AS 'FromDate'
              ,DATEADD(ss,-1,DATEADD(YEAR,1,@StartingDate)) as 'ToDate'
              ,1 AS MyRowNumber
            UNION ALL
            SELECT DATEADD(ss,1,ToDate) as 'FromDate'
              ,DATEADD(YEAR,1,ToDate) as 'ToDate'
              ,MyRowNumber + 1 AS MyRowNumber
            FROM YearPeriod
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
        ) INSERT INTO @DateResults (FromDate, ToDate, MyRowNumber) SELECT * FROM YearPeriod
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
      END
      ELSE IF (@StartingDateIsFocus = 0)
      BEGIN
        WITH YearPeriod AS
        (
            SELECT DATEADD(ss,1,DATEADD(YEAR,-1,@EndingDate)) as 'FromDate'
              ,@EndingDate AS 'ToDate'
              ,1 AS MyRowNumber
            UNION ALL
            SELECT DATEADD(ss,1,DATEADD(YEAR,-1,FromDate)) as 'FromDate'
              ,DATEADD(ss,-1,DATEADD(YEAR,-1,ToDate)) as 'ToDate'
              ,MyRowNumber + 1 AS MyRowNumber
            FROM YearPeriod
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
        ) INSERT INTO @DateResults (FromDate, ToDate, MyRowNumber) SELECT * FROM YearPeriod
            WHERE (     (MyRowNumber <= @NumberOfPeriods)
                     OR (@NumberOfPeriods IS NULL)
                  )
            AND FromDate >= @StartingDate
            AND ToDate <= @EndingDate
            AND MyRowNumber < 99
      END
    END
    RETURN
  END

0 个答案:

没有答案