【问题标题】:How to split date ranges based on months in SQL Server 2005如何在 SQL Server 2005 中根据月份拆分日期范围
【发布时间】:2012-01-24 10:52:00
【问题描述】:

例如:日期范围是 01-01-201101-01-2012,我想要这样的输出:

 01-01-2011 31-01-2011
 01-02-2011 28-02-2011

我该怎么做?我正在使用 SQL Server 2005..

谢谢

【问题讨论】:

    标签: sql sql-server-2005


    【解决方案1】:

    使用 CTE:

    DECLARE @Begin DATETIME
    DECLARE @End DATETIME
    
    SELECT @Begin = '20110101', @End = '20120101'
    
    ;WITH ranges(DateFrom, DateTo) AS
    (
      SELECT @Begin, DATEADD(DAY, -1, DATEADD(MONTH, 1, @begin))
      UNION ALL
      SELECT DATEADD(month, 1, DateFrom), DATEADD(DAY, -1, DATEADD(MONTH, 2, DateFrom))
      FROM ranges
      WHERE DateFrom < @End
    )
    SELECT * FROM ranges
    OPTION(MAXRECURSION 0)
    

    并且不使用 CTE:

    DECLARE @Begin DATETIME
    DECLARE @End DATETIME
    
    SELECT @Begin = '20110101', @End = '20120101'
    
    SELECT DATEADD(MONTH, n.Number, @Begin) DateFrom, DATEADD(day, -1, DATEADD(MONTH, n.Number+1, @Begin)) DateTo
    FROM master.dbo.spt_values n
    WHERE 
        n.Number < DATEDIFF(MONTH, @begin, @end)
    AND n.Type = 'P'
    

    如果您还需要包含 2012 年 1 月,请使用此

    DECLARE @Begin DATETIME
    DECLARE @End DATETIME
    
    SELECT @Begin = '20110101', @End = '20120101'
    
    SELECT DATEADD(MONTH, n.Number, @Begin) DateFrom, DATEADD(day, -1, DATEADD(MONTH, n.Number+1, @Begin)) DateTo
    FROM master.dbo.spt_values n
    WHERE 
        n.Number <= DATEDIFF(MONTH, @begin, @end)
    AND n.Type = 'P'
    

    和 CTE:

    DECLARE @Begin DATETIME
    DECLARE @End DATETIME
    
    SELECT @Begin = '20110101', @End = '20120101'
    
    ;WITH ranges(DateFrom, DateTo) AS
    (
      SELECT @Begin, DATEADD(DAY, -1, DATEADD(MONTH, 1, @begin))
      UNION ALL
      SELECT DATEADD(month, 1, DateFrom), DATEADD(DAY, -1, DATEADD(MONTH, 2, DateFrom))
      FROM ranges
      WHERE DATEADD(month, 1, DateFrom) < @End
    )
    SELECT * FROM ranges
    OPTION(MAXRECURSION 0)
    

    【讨论】:

    • 除了使用 CTE 还有其他方法吗?
    • 是的,但它们可能不太简洁且难以理解。为什么要避免 CTE?
    • @OlegDok:此查询未返回 2012 年 1 月的任何内容。
    • @MarkBannister 应该吗?所以 - 更正了所有查询以返回 2012 年 1 月而不是返回
    【解决方案2】:
    >On Providing the Start and End Date range, it can be split into months. This might help.
    DECLARE @StartDate   datetime 
    DECLARE @EndDate     datetime
    DECLARE @tmpStart    datetime
    DECLARE @tmpEnd      datetime
    
    Select @StartDate   = '2012-01-01'
    Select @EndDate     = '2009-01-01'
    
    Select @StartDate = DATEADD(MONTH,1,Convert(DATETIME,Convert(VARCHAR(25), Datepart (YEAR,@StartDate)) + '-' +  Convert(VARCHAR(25), Datepart(MONTH, @StartDate)) + '-' + Convert(VARCHAR(25), 1))) 
    
    Select @EndDate = DATEADD(MONTH,1,Convert(DATETIME,Convert(VARCHAR(25), Datepart(YEAR, @EndDate)) + '-' + Convert(VARCHAR(25), Datepart(MONTH, @EndDate)) + '-' + Convert(VARCHAR(25), 1)))
    
    Select @EndDate = DATEADD(DD,-1, DATEADD(MM,1,@EndDate))
    
    Select @tmpEnd = @EndDate
    Select @tmpStart = Convert(DATETIME,Convert(VARCHAR(25), Datepart(YEAR, @tmpEnd)) + '-' + 
                      Convert(VARCHAR(25), Datepart(MONTH, @tmpEnd)) + '-' + Convert(VARCHAR(25), 1)) 
    
    Select @StartDate 'Start' , @EndDate 'End' 
    
    While @tmpStart <= @StartDate 
    BEGIN   
        Select @tmpStart 'tmpStart' , @tmpEnd 'tmpEnd'  
        Select @tmpStart = DATEADD(MM,1,@tmpStart)
        Select @tmpEnd   = DATEADD(DD,-1,DATEADD (MM, 1 , @tmpStart)) 
    END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-03
      • 2021-05-25
      相关资源
      最近更新 更多