【问题标题】:How to get a list of months between 2 given dates using a query?如何使用查询获取两个给定日期之间的月份列表?
【发布时间】:2011-10-19 02:35:15
【问题描述】:

我有 2 个日期,例如 2011 年 3 月 28 日和 2011 年 6 月 29 日。我需要一个 sql 查询来显示这两个日期之间的月份,包括包含日期的月份,即。六月、五月、四月和三月。

【问题讨论】:

    标签: oracle date-arithmetic


    【解决方案1】:

    类似的东西

    SQL> ed
    Wrote file afiedt.buf
    
        select to_char( add_months( start_date, level-1 ), 'fmMonth' )
          from (select date '2011-03-30' start_date,
                       date '2011-06-29' end_date
                  from dual)
         connect by level <= months_between(
                               trunc(end_date,'MM'),
                               trunc(start_date,'MM') )
      *                      + 1
    SQL> /
    
    TO_CHAR(ADD_MONTHS(START_DATE,LEVEL-
    ------------------------------------
    March
    April
    May
    June
    

    应该可以。

    【讨论】:

    • 好吧,即使是盲松鼠也会偶尔发现坚果。
    【解决方案2】:

    将添加此解决方案只是因为我认为它比其他解决方案更清洁:

    SELECT ADD_MONTHS(TRUNC(TO_DATE('28-Mar-2011', 'DD-MON-YYYY'), 'MON'), ROWNUM - 1) date_out
    FROM   DUAL
    CONNECT BY ADD_MONTHS(TRUNC(TO_DATE('28-Mar-2011', 'DD-MON-YYYY'), 'MON'), ROWNUM - 1)
        <= TRUNC(TO_DATE('29-Jun-2011', 'DD-MON-YYYY'), 'MON')
    

    【讨论】:

      【解决方案3】:

      你可以使用函数MONTHS_BETWEEN

      SELECT MOD( TRUNC( MONTHS_BETWEEN( '2011-07-29', '2011-03-28' ) ), 12 ) as MONTHS
      FROM DUAL
      

      输出

          MONTHS
      ----------
               4
      

      【讨论】:

      • 我需要月份作为输出,即。三月、四月、五月和六月。不是 4。
      • 对不起,我误解了你的问题。你应该检查贾斯汀洞穴的答案。没错。
      【解决方案4】:

      几天前我需要一个答案。我找到了另一个我更喜欢的解决方案:

      select to_char(which_month, 'Mon-yyyy') month
      from
      (
          select
              add_months(to_date(:start_date,'mm-yyyy'), rownum-1) which_month
          from
              all_objects
          where
              rownum <= months_between(to_date(:end_date,'mm-yyyy'), add_months(to_date(:start_date,'mm-yyyy'), -1))
          order by
              which_month
      )
      

      您当然可以使用任何您想要的格式。我对另一组“联合”并求和,这样即使没有结果,我也能得到月份。

      【讨论】:

      • 感激,准确回答我想要的:)
      【解决方案5】:
      SELECT MIN (to_date((TO_CHAR (Actual_Date, 'DD-MM-RRRR')),'dd-mm-rrrr')) F_DATE,
               MAX (to_date((TO_CHAR (Actual_Date, 'DD-MM-RRRR')),'dd-mm-rrrr')) T_DATE,
               TO_CHAR (Actual_Date, 'MM-RRRR') TRX_MONTH     
          FROM (    SELECT TRUNC (TO_DATE (:P_FDATE, 'dd-mm-rrrr')) + LEVEL - 1
                              Actual_Date
                      FROM (SELECT TRUNC (TO_DATE (:P_FDATE, 'dd-mm-rrrr'), 'MM') - 1
                                      AS dt
                              FROM DUAL)
                CONNECT BY LEVEL <=
                              (  TO_DATE (:P_TDATE, 'dd-mm-rrrr')
                               - TRUNC (TO_DATE (:P_FDATE, 'dd-mm-rrrr'))
                               + 1))
      GROUP BY TO_CHAR (Actual_Date, 'MM-RRRR')
      ORDER BY 1
      

      【讨论】:

      • 请将代码缩进 4 个空格以激活语法高亮。此外,通常会感谢添加一些解释性文字(特别是如果已经有公认的答案,请说出您的解决方案有何不同)。
      【解决方案6】:
           declare 
              v_date_from_first_day date;
              v_date_to_last_day date;
              v_month_name varchar2(10);
              v_month_number number;
              v_year_number number;
              v_month_diff number;
              begin
                v_date_to_last_day := to_date('31.12.2018'); 
                v_date_from_first_day := to_date('01.01.2018');
      
                select months_between(v_date_to_last_day,v_date_from_first_day) as diff into v_month_diff from dual;
      
                for i in 1..round(v_month_diff, 2) loop
                select 
                to_char(trunc(add_months(v_date_to_last_day - months_between(v_date_from_first_day, v_date_to_last_day), -i)), 'fmMonth') as month_nm,
                to_char(trunc(add_months(v_date_to_last_day - months_between(v_date_from_first_day, v_date_to_last_day), -i)), 'MM') as month_num,
                to_char(trunc(add_months(v_date_to_last_day - months_between(v_date_from_first_day, v_date_to_last_day), -i)), 'YYYY') as year_num
                into v_month_name, v_month_number, v_year_number
                from dual;
      
                dbms_output.put_line(v_month_number || '/' || v_year_number);
      dbms_output.put_line(v_month_name || '/' || v_year_number);
                end loop;
              end;
      
              Output: 
              12/2018
              11/2018
              10/2018
              9/2018
              8/2018
              7/2018
              6/2018
              5/2018
              4/2018
              3/2018
              2/2018
              1/2018
      

      这里,月份名称是克罗地亚语

      Prosinac/2018
      Studeni/2018
      Listopad/2018
      Rujan/2018
      Kolovoz/2018
      Srpanj/2018
      Lipanj/2018
      Svibanj/2018
      Travanj/2018
      Ožujak/2018
      Veljača/2018
      Siječanj/2018
      

      【讨论】:

      • 您好,欢迎来到 SO,请阅读How to Answer 上的指南。您还可以更好地记录您的 Codesample 以帮助人们了解它的作用。
      • 对不起。我第一次来这里。未来我会做得更好。
      • 没关系 :) 一定要纠正它,让它对阅读它的人尽可能有用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多