Как получить список месяцев между двумя заданными датами с помощью запроса?

У меня есть две даты, скажем, 28 марта 2011 года и 29 июня 2011 года. Мне нужен запрос sql, который будет отображать месяцы между этими двумя датами, включая месяцы, содержащие даты, т.е. Июнь, май, апрель и март.


person Nitish    schedule 03.08.2011    source источник


Ответы (6)


Что-то вроде этого

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

должно сработать.

person Justin Cave    schedule 03.08.2011
comment
Ну, даже слепая белка находит случайный орех. - person Justin Cave; 03.08.2011

Собираюсь добавить это решение только потому, что я думаю, что оно намного чище, чем другие:

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')
person Reimius    schedule 23.07.2013

Вы можете использовать функцию МЕСЯЦА_МЕЖДУ.

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

Выход

    MONTHS
----------
         4
person bruno    schedule 03.08.2011
comment
Мне нужны месяцы в качестве вывода, т.е. Март, апрель, май и июнь. Не 4. - person Nitish; 03.08.2011
comment
Извините, я неправильно понял ваш вопрос. Вы должны проверить ответ Джастина Кейва. Верно. - person bruno; 03.08.2011

Мне нужен был ответ на этот вопрос пару дней назад. Я нашел другое решение, которое мне понравилось больше:

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
)

Конечно, вы можете использовать любой формат. Я объединил и суммировал по другому набору, чтобы получить месяцы, даже если у них не было результатов.

person Rubenisme    schedule 21.09.2012
comment
Оценил, точный ответ, что я хочу :) - person John; 29.11.2015

     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
person Bruno Blaugrana Kucevic    schedule 15.01.2019
comment
Привет и добро пожаловать в SO, прочитайте руководство по Как ответить. Вы также можете немного лучше задокументировать свой пример кода, чтобы помочь людям понять, что он делает. - person LuckyLikey; 15.01.2019
comment
Извиняюсь. Мой первый раз здесь. Я сделаю лучше в будущем. - person Bruno Blaugrana Kucevic; 15.01.2019
comment
неважно :) Просто обязательно исправьте его, чтобы сделать его максимально полезным для всех, кто его читает. - person LuckyLikey; 15.01.2019

person    schedule
comment
Сделайте отступ в коде на 4 пробела, чтобы активировать подсветку синтаксиса. Кроме того, обычно приветствуется добавление небольшого поясняющего текста (особенно если уже есть принятые ответы, скажите, что отличает ваше решение). - person chtz; 24.12.2016