Oracle SQL. Получить даты между двумя датами - PullRequest
1 голос
/ 09 июля 2020

У меня есть таблица с двумя столбцами дат, как получить даты между этими двумя датами и перечислить их одну за другой. Вот тестовый сценарий:

CREATE TABLE t1
   AS
      SELECT DATE '2020-1-31' AS startdate,
             DATE '2020-2-3' AS enddate
      FROM dual
      UNION
      SELECT DATE '2020-2-27' AS startdate,
             DATE '2020-3-3' AS enddate
      FROM dual;

SELECT *
FROM t1;


DROP TABLE t1;

Ожидаемый результат:

введите описание изображения здесь

Как мне сделать запрос? Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 09 июля 2020

Альтернативное решение

Создание таблицы -

create table mytable(start_date date, end_date date);

Загрузка данных -

insert into mytable values (to_date('01/31/2020','mm/dd/yyyy'),to_date('02/03/2020','mm/dd/yyyy'));

SQL для получения списка дат между заданным диапазоном дат -

select
   t.start_date + rownum -1 as dt,
   t.start_date,
   t.end_date
from
   all_objects, mytable t
where
   rownum <=
   t.end_date- t.start_date+1;

скрипт db - https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=7cd81f5892ad195b72ee1d22a3b44e2a

1 голос
/ 09 июля 2020

Для актуальных Oracle версий:

SELECT *
FROM t1,
     lateral(
           select level N,
                  t1.startdate+level-1 dt
           from dual
           connect by level <= t1.enddate - t1.startdate + 1
     );

или

SELECT 
  startdate,
  enddate,
  startdate+n as DT
FROM t1,
     xmltable('0 to xs:integer(.)' 
              passing cast(enddate-startdate as number)
               columns n int path '.'
             )

Полные примеры:

with t1
   AS (
      SELECT DATE '2020-1-31' AS startdate,
             DATE '2020-2-3' AS enddate
      FROM dual
      UNION
      SELECT DATE '2020-2-27' AS startdate,
             DATE '2020-3-3' AS enddate
      FROM dual
)
SELECT *
FROM t1,
     lateral(
           select level N,
                  t1.startdate+level-1 dt
           from dual
           connect by level <= t1.enddate - t1.startdate + 1
     );

with t1
   AS (
      SELECT DATE '2020-1-31' AS startdate,
             DATE '2020-2-3' AS enddate
      FROM dual
      UNION
      SELECT DATE '2020-2-27' AS startdate,
             DATE '2020-3-3' AS enddate
      FROM dual
)
SELECT 
  startdate,
  enddate,
  startdate+n as DT
FROM t1,
     xmltable('0 to xs:integer(.)' 
              passing cast(enddate-startdate as number)
               columns n int path '.'
             );
1 голос
/ 09 июля 2020

Вот go:

SQL> select * From t1;

STARTDATE  ENDDATE
---------- ----------
01/31/2020 02/03/2020
02/27/2020 03/03/2020

SQL> select a.startdate, a.enddate,
  2    a.startdate + column_value - 1 dt
  3  from t1 a cross join
  4    table(cast(multiset(select level from dual
  5                        connect by level <= a.enddate - a.startdate + 1
  6                       ) as sys.odcinumberlist))
  7  order by dt;

STARTDATE  ENDDATE    DT
---------- ---------- ----------
01/31/2020 02/03/2020 01/31/2020
01/31/2020 02/03/2020 02/01/2020
01/31/2020 02/03/2020 02/02/2020
01/31/2020 02/03/2020 02/03/2020
02/27/2020 03/03/2020 02/27/2020
02/27/2020 03/03/2020 02/28/2020
02/27/2020 03/03/2020 02/29/2020
02/27/2020 03/03/2020 03/01/2020
02/27/2020 03/03/2020 03/02/2020
02/27/2020 03/03/2020 03/03/2020

10 rows selected.

SQL>

Это называется методом генератора строк (если вы когда-нибудь захотите использовать Google для этого).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...