【问题标题】:Get Quarters StartDate and EndDate from Year从年份获取季度 StartDate 和 EndDate
【发布时间】:2013-09-17 07:51:44
【问题描述】:

我正在使用 SQL Server 2008。我想获取一年中所有季度的开始日期和结束日期。例如,如果我在查询中传递 2013,那么输出应该像

StartDate                 EndDate                   QuarterNo
-------------------------------------------------------------
2013-04-01 00:00:00.000   2013-06-30 00:00:00.000      1
2013-07-01 00:00:00.000   2013-09-30 00:00:00.000      2
2013-10-01 00:00:00.000   2013-12-31 00:00:00.000      3
2014-01-01 00:00:00.000   2014-03-31 00:00:00.000      4

由于财政年度从 4 月 1 日开始,我想从 4 月 1 日开始获得第一季度。我怎样才能得到这个输出?感谢您的帮助...

【问题讨论】:

    标签: sql-server sql-server-2008


    【解决方案1】:
    select 
        dateadd(M, 3*number, CONVERT(date, CONVERT(varchar(5),@year)+'-1-1')),
        dateadd(D,-1,dateadd(M, 3*number+3, CONVERT(date, CONVERT(varchar(5),@year)+'-1-1'))),
        Number QuarterNo
    from master..spt_values 
    where type='p' 
    and number between 1 and 4  
    

    您可能希望使用日期,而不是日期时间,否则季度最后一天的任何内容都不会包含在您的季度中(例如:2013-06-30 14:15)

    反之,请使用datepart

    select ((DATEPART(q,@date)+2) % 4)+1
    

    【讨论】:

      【解决方案2】:

      我最喜欢的方式,但 EOMONTH 和 DATEFROMPARTS 在 SQLServer 2012 之前不存在:

      DECLARE
          @FISCAL_YEAR INT = 2013,
          @QUATER INT = 2
      SELECT 
          DATEFROMPARTS(@fiscal_year,(@Quater * 3)-2,1) AS QuaterStart,
          EOMONTH(DATEFROMPARTS(@fiscal_year,@Quater * 3,1)) AS QuaterEnd 
      

      【讨论】:

        【解决方案3】:

        另一种方法

        SELECT DATEADD(mm, (quarter - 1) * 3, year_date) StartDate,
               DATEADD(dd, -1, DATEADD(mm, quarter * 3, year_date)) EndDate,
               quarter QuarterNo
          FROM
        (
          SELECT '2013-04-01' year_date
        ) s CROSS JOIN 
        (
          SELECT 1 quarter UNION ALL
          SELECT 2 UNION ALL
          SELECT 3 UNION ALL
          SELECT 4
        ) q
        

        输出:

        |开始日期 |结束日期 |季号 | |------------|------------|------------| | 2013-04-01 | 2013-06-30 | 1 | | 2013-07-01 | 2013-09-30 | 2 | | 2013-10-01 | 2013-12-31 | 3 | | 2014-01-01 | 2014-03-31 | 4 |

        这里是SQLFiddle演示

        【讨论】:

          【解决方案4】:

          在寻找截断日期时偶然发现了这两个帖子。

          -- DATE TRUNCATE FORMAT
          CAST(DATEADD(datepart, DATEDIFF(datepart, 0, date), 0) AS DATE)
          

          这是我写的一个示例查询,可能会有所帮助:

          DECLARE @datetime DATETIME = GETDATE() -- '2021-08-21 16:48:09.018'
          
          SELECT
            @datetime                                                                                       AS [Date Time]
          , CAST(@datetime AS DATE)                                                                         AS [Date]
          , DATEPART(QUARTER, @datetime)                                                                    AS [Quarter of Year]
          , DATEDIFF(QUARTER, 0, @datetime)                                                                 AS [Quarter Integer]
          , DATEDIFF(QUARTER, 0, @datetime) - 1                                                             AS [Previous Quarter Integer]
          , DATEDIFF(QUARTER, 0, @datetime) + 1                                                             AS [Next Quarter Integer]
          , CAST(DATEADD(QUARTER, DATEDIFF(QUARTER, 0, @datetime), 0) AS DATE)                              AS [Quarter Date 1]
          , DATEFROMPARTS(YEAR(@datetime), (DATEPART(QUARTER, @datetime) * 3) - 2, 1)                       AS [Quarter Date 2]
          , CAST(DATEADD(QUARTER, DATEDIFF(QUARTER, 0, @datetime) - 1, 0) AS DATE)                          AS [Previous Quarter Start Date 1]
          , DATEADD(QUARTER, -1, DATEFROMPARTS(YEAR(@datetime), (DATEPART(QUARTER, @datetime) * 3) - 2, 1)) AS [Previous Quarter Start Date 2]
          , CAST(DATEADD(QUARTER, DATEDIFF(QUARTER, 0, @datetime) + 1, 0) AS DATE)                          AS [Next Quarter Start Date 1]
          , DATEADD(QUARTER, +1, DATEFROMPARTS(YEAR(@datetime), (DATEPART(QUARTER, @datetime) * 3) - 2, 1)) AS [Next Quarter Start Date 2]
          , EOMONTH(DATEFROMPARTS(YEAR(@datetime), DATEPART(QUARTER, @datetime) * 3, 1))                    AS [Quarter End Date 1]
          , CAST(DATEADD(DAY, -1, DATEADD(QUARTER, DATEDIFF(QUARTER, 0, @datetime) + 1, 0)) AS DATE)        AS [Quarter End Date 2]
          , CAST(DATEADD(DAY, -1, DATEADD(QUARTER, DATEDIFF(QUARTER, 0, @datetime), 0)) AS DATE)            AS [Previous Quarter End Date]
          , CAST(DATEADD(DAY, -1, DATEADD(QUARTER, DATEDIFF(QUARTER, 0, @datetime) + 2, 0)) AS DATE)        AS [Next Quarter End Date]
          

          【讨论】:

            【解决方案5】:
             CREATE FUNCTION cal_quarter (@DATE SMALLDATETIME)
            
                RETURNS INT
                AS
            BEGIN
            declare @CalendarQuarter int
                    IF month(@DATE) in(4,5,6)
                        BEGIN
                            set @CalendarQuarter =1
                        END
                    if month(@DATE) in(7,8,9)
                        BEGIN
                            set @CalendarQuarter =2
                        END
                    if month(@DATE) in(10,11,12)
                        BEGIN
                            set @CalendarQuarter =3
                        END
                    if month(@DATE) in(1,2,3)
                        BEGIN
                            set @CalendarQuarter =4
                        END
            return @CalendarQuarter
            END
            

            这是一个返回日历季度的函数。

            您应该发送DATE 作为参数。

            希望这会有所帮助!

            【讨论】:

              【解决方案6】:

              上一季度的最后日期。此代码可以在 SQL Server 2012 及更高版本上运行

              select EOMONTH(DATEFROMPARTS(year(DATEADD(month, -1, GETDATE())),DATENAME(qq,DATEADD(month, -1, GETDATE())) * 3,1)) AS QuarterEnd 
              

              【讨论】:

              • 问题是针对 SQL Server 2008
              • @AnuraagBaishya 当然,但更新不会造成任何伤害。 Mahabubuzzaman 您是否介意更好地格式化您的代码以防止 hor.滚动并添加简要说明?
              • DATEFROMPARTS 创建了所述月份的第一个日期,EOMONTH 返回所述月份的最后一个日期。
              【解决方案7】:

              这是使用递归 CTE 的日历季度解决方案。

              DECLARE @Date DATE = '2021-11-06'
              
              ;WITH CalendarQuarters
              AS
              (
                  SELECT 1 AS QuarterNo
                        ,CONVERT(DATE,DATEADD(DAY,-(DATEPART(DAY,@Date))+1, DATEADD(MONTH,-(DATEPART(MONTH,@Date))+1,@Date))) AS StartDate
                        ,CONVERT(DATE,DATEADD(DAY,-(DATEPART(DAY,@Date)), DATEADD(MONTH,-(DATEPART(MONTH,@Date))+4,@Date))) AS EndDate
                  UNION ALL
                  SELECT 
                         QuarterNo + 1
                        ,CONVERT(DATE,DATEADD(DAY,-(DATEPART(DAY,@Date))+1, DATEADD(MONTH,-(DATEPART(MONTH,@Date))+1+QuarterNo*3,@Date))) AS StartDate
                        ,CONVERT(DATE,DATEADD(DAY,-(DATEPART(DAY,@Date)), DATEADD(MONTH,-(DATEPART(MONTH,@Date))+4+QuarterNo*3,@Date))) AS EndDate
                  FROM CalendarQuarters
                  WHERE QuarterNo < 4
              )
              
              SELECT * FROM CalendarQuarters
              

              【讨论】:

                【解决方案8】:
                SELECT 
                    CAST(DATEADD(M,3*(NUMBER-1),DATEADD(YYYY,DATEDIFF(YYYY,0,GETDATE()),0)) AS DATE) [QT START DATE]
                    , CAST(DATEADD(D,-1,DATEADD(M,3*(NUMBER),DATEADD(YYYY,DATEDIFF(YYYY,0,GETDATE()),0))) AS DATE) [QT END DATE]
                    , NUMBER AS [QUARTER NAME]
                FROM MASTER..SPT_VALUES 
                WHERE TYPE='P' 
                    AND NUMBER BETWEEN 1 AND 4
                

                【讨论】:

                  猜你喜欢
                  • 2019-05-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-03-08
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多