【问题标题】:How to find the last day of a Quarter, Half Year and Year of current Financial Year in DB2?如何在 DB2 中找到当前财政年度的季度、半年和年度的最后一天?
【发布时间】:2017-02-10 09:13:11
【问题描述】:

我想在 DB2 中获取当前财政年度的季度、半年和年度的最后一天。我们的财政年度从 4 月 1 日开始,到 3 月 31 日结束。因此,如果今天的日期是 2016 年 10 月 2 日,则季度结束日期将为 2016 年 12 月 31 日,半年日期将为 2017 年 3 月 31 日,年结束日期为 2017 年 3 月 31 日。同样,如果输入日期为 2016 年 5 月 7 日,则季度结束日期为 2016 年 6 月 30 日,半年日期为 2016 年 9 月 30 日,年结束日期为 2017 年 3 月 31 日。

我可以使用 DB2 中的 last_day 函数获取一个月的最后一个日期,但我无法获取其他 3 个日期。对于这方面的任何帮助,我将不胜感激。

【问题讨论】:

  • 创建一个 FiscalDates DB2 表并使用您在问题中提到的日期加载它。

标签: sql date db2


【解决方案1】:

计算一个季度内的月份数(即 1/2/3),然后为一个季度的第 1 个月加上 2 个月,为第 2 季度加上 1 个月(MOD(2-(MONTH(CURRENT_DATE)-1),3) = 0/1/2) .现在您的月份总是 3/6/9/12,您可以申请 last_day。

我没有DB2系统来测试,但是语法好像是这样的:

LAST_DAY(CURRENT_DATE + (MOD(2-(CURRENT_DATE-1),3) MONTH))

【讨论】:

    【解决方案2】:

    您可以对日期做一些非常灵活的事情,但在 DB2(据我所知)中并没有什么特别的东西能够找到相关财务季度的日期,所以当月的一些案例陈述可能是需要。

    SELECT MONTH(CURRENT DATE), -- returns 10
    
           CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS, --return first day of current month
    
           CASE WHEN 
                   MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3) = 0
                   THEN 3
              ELSE MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3)
           END, --months into the quarter, so 1 for first month, 2 for second month, 3 for last month
    
    
           CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS +
           (4 - CASE WHEN 
                      MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3) = 0
                       THEN 3
                     ELSE MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3)
           END) MONTHS, --returns first day of next quarter
    
    
           CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS +
                          (4 - CASE WHEN 
                                        MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3) = 0
                                          THEN 3
                                    ELSE MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3)
                           END) MONTHS
           - 1 DAY -- returns last day of current quarter
    FROM SYSIBM.SYSDUMMY1
    

    然后,您可以使用当月前后的一些案例陈述来查找半年和明年的类似信息。

    我知道这看起来有点乱,但它会完成这项工作。我建议使用此代码创建一个标量函数,您可以轻松地重复使用该函数来查找季度,并且在半年和全年都有类似的结果。

    资料来源:作为商业智能分析师每天使用 DB2 工作

    【讨论】:

      【解决方案3】:

      此处给出的查询和例程的验证是在 DB2 for IBM i 7.3 [aka v7r3] 上完成的

      没有说明如何使用数据 [以便了解需要或可以以何种形式提供数据],但以下用户定义的表函数 (UDTF) 定义了一些常量,这些常量表示来自传入的 MONTH [作为输入的可选日期;如果没有提供参数,则默认为 CURRENT DATE]、季末和半年末的​​月份以及季度;该映射允许一些相当简单的日期算术来提供所需的值,而无需创建实际的 [持久] 日历表:

      create function OUR_FINANCIAL_YEAR_DATES                       
      ( input_date date default current date )                       
      returns table                                                  
      ( "Last_Day_Of_Quarter"   /* for LD_QTR  */ date               
      , "Last_Day_Of_Half_Year" /* for LD_HALF */ date               
      , "Last_Day_Of_Year"      /* for LD_YEAR */ date               
      ) language sql                                                 
      return                                                         
       with                                                          
         moMap ( mo, hAddMo, qAddMo, q ) as ( values                 
            ( 12, 3 , 0 , 3 ), ( 11, 4 , 1 , 3 ), ( 10, 5 , 2 , 3 )  
          , (  9, 0 , 0 , 2 ), (  8, 1 , 1 , 2 ), (  7, 2 , 2 , 2 )  
          , (  6, 3 , 0 , 1 ), (  5, 4 , 1 , 1 ), (  4, 5 , 2 , 1 )  
          , (  3, 0 , 0 , 4 ), (  2, 1 , 1 , 4 ), (  1, 2 , 2 , 4 ) )
       , endFYdates ( end_Qtr, end_Hyr, end_Fyr ) as                 
         ( select                                                    
             last_day( input_date   +  qAddMo MONTHS )     as Qtr_end
           , last_day( input_date   +  hAddMo MONTHS )     as Hyr_end
           , last_day( input_date   + (qAddMo + ( 3 * ( 4 - q ) )    
                                      )       MONTHS )     as Fyr_end
           from moMap as M                                           
           where mo = month( input_date   )                          
         )                                                           
       select end_Qtr, end_Hyr, end_Fyr                              
       from endFYdates                                               
      

      当然,标量用户定义函数 (UDF) 可以很容易地使用上述 UDTF 来实现获取其中任何一个值;可能带有第二个参数,用于标识要返回哪些 DATE 值。

      with                                                                
        variousDates ( dv ) as ( values                                   
        ( date'2016-05-01' ), ( date'2016-05-02' ), ( date'2016-06-30' )  
      , ( date'2016-07-02' ), ( date'2016-08-02' ), ( date'2016-09-30' )  
      , ( date'2016-10-01' ), ( date'2016-11-02' ), ( date'2016-12-30' )  
      , ( date'2017-01-02' ), ( date'2017-03-02' ), ( date'2017-03-30' ) )
      select vdv.*, fyv.*                                                 
           , dec( quarter( vdv.dv - 3 months ) , 1 ) as qtr               
      from variousDates as vdv                                            
      , lateral                                                           
        ( select s.* from table(OUR_FINANCIAL_YEAR_DATES(vdv.dv)) as s    
        ) as fyv                                                          
      order by 1                                                          
      ; -- a likeness of a report from the above query:
      DV          LAST_00001  LAST_00002  LAST_00003  QTR
      2016-05-01  2016-06-30  2016-09-30  2017-03-31   1 
      2016-05-02  2016-06-30  2016-09-30  2017-03-31   1 
      2016-06-30  2016-06-30  2016-09-30  2017-03-31   1 
      2016-07-02  2016-09-30  2016-09-30  2017-03-31   2 
      2016-08-02  2016-09-30  2016-09-30  2017-03-31   2 
      2016-09-30  2016-09-30  2016-09-30  2017-03-31   2 
      2016-10-01  2016-12-31  2017-03-31  2017-03-31   3 
      2016-11-02  2016-12-31  2017-03-31  2017-03-31   3 
      2016-12-30  2016-12-31  2017-03-31  2017-03-31   3 
      2017-01-02  2017-03-31  2017-03-31  2017-03-31   4 
      2017-03-02  2017-03-31  2017-03-31  2017-03-31   4 
      2017-03-30  2017-03-31  2017-03-31  2017-03-31   4 
      ********  End of data  ********                    
      

      以下 UDTF 计算作为输入的给定 DATE 值的 End-Of-Quarter [对于 CURRENT_DATE,如果没有传递参数],但另外计算并提供 Start-Of-从该计算日期开始的每个季度的 Quarter 和 End-Of_Quarter 值,加上提供给定 DATE 值的半年末、年末和季度的计算结果:

      create function THE_FINANCIAL_YEAR_DATES          
      ( input_date date default current date )          
      returns table                                     
      ( LastOfQtr               /* for LD_QTR  */ date  
      , LastOfHalf              /* for LD_HALF */ date  
      , LastOfYear              /* for LD_YEAR */ date  
      , NumberQtr               /* for NO_QTR  */ dec(1)
      , FirstOfQ1               /* for FD_Q1   */ date  
      , Last_OfQ1               /* for LD_Q1   */ date  
      , FirstOfQ2               /* for FD_Q2   */ date  
      , Last_OfQ2               /* for LD_Q2   */ date  
      , FirstOfQ3               /* for FD_Q3   */ date  
      , Last_OfQ3               /* for LD_Q3   */ date  
      , FirstOfQ4               /* for FD_Q4   */ date  
      , Last_OfQ4               /* for LD_Q4   */ date  
      ) language sql                                    
      return                                                              
       with                                                               
         endCurQtr  ( ecq , q ) as                                        
           ( values                                                       
              ( LAST_DAY(   input_date                                    
                          + ( MOD( 1 - MONTH( input_date )                
                                 , 3 ) + 2                                
                            ) MONTHS                                      
                        )                                                 
              , DEC( QUARTER( input_date - 3 MONTHS ), 1 )                
              )                                                           
           )                                                              
      , curFYdates (q, ecq, sQ1, eQ1, sQ2, eQ2, sQ3, eQ3, sQ4, eQ4, eHY) as
        ( select q, ecq,                                                  
            ( ecq + 1 day )   - (   3 * ( q     )  ) months               
          , last_day( ( ecq ) - (   3 * ( q - 1 )  ) months )             
          , ( ecq + 1 day )   - (   3 * ( q - 1 )  ) months               
          , last_day( ( ecq ) - (   3 * ( q - 2 )  ) months )        
          , ( ecq + 1 day )   - (   3 * ( q - 2 )  ) months          
          , last_day( ( ecq ) - (   3 * ( q - 3 )  ) months )        
          , ( ecq + 1 day )   - (   3 * ( q - 3 )  ) months          
          , last_day( ( ecq ) - (   3 * ( q - 4 )  ) months )        
          , last_day( ( ecq ) - (   3 * ( q -                        
                 case when q>2 then 4 else 2 end)  ) months )        
          from endCurQtr                                             
        )                                                            
      select ecq, eHY, eQ4, q, sQ1, eQ1, sQ2, eQ2, sQ3, eQ3, sQ4, eQ4
      from curFYdates                                                
      

      【讨论】:

        【解决方案4】:

        这是我用来计算上一季度最后一天的:

        SELECT 
        CASE WHEN MONTH(CURRENT DATE) BETWEEN 1 AND 3 
        THEN DATE(YEAR(CURRENT DATE) -1 || '-12-31')  
        WHEN MONTH(CURRENT DATE) BETWEEN 4 AND 6 
        THEN DATE(YEAR(CURRENT DATE) || '-03-31') 
        WHEN MONTH(CURRENT DATE) BETWEEN 7 AND 9 
        THEN DATE(YEAR(CURRENT DATE) || '-06-30') 
        WHEN MONTH(CURRENT DATE) BETWEEN 10 AND 12 
        THEN DATE(YEAR(CURRENT DATE) || '-09-30')END AS QTR_END 
        FROM SYSIBM.SYSDUMMY1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-26
          • 1970-01-01
          • 1970-01-01
          • 2015-08-10
          • 1970-01-01
          相关资源
          最近更新 更多