Home > database >  (Oracle SQL) Need to get the startdate and enddate of a date column and return dates for each day
(Oracle SQL) Need to get the startdate and enddate of a date column and return dates for each day

Time:03-22

I have a date column and I need to return each day from the start date to the end date. For example if I have a date column that starts at 01-01-2020 till 22/03/2022. Then I want to return data such as:

DateColumn
01-JAN-20
02-JAN-20
03-JAN-20
and so on......
until 22-MAR-22

CodePudding user response:

From Oracle 12:

SELECT t.id, d.day
FROM   table_name t
       CROSS JOIN LATERAL (
         SELECT t.start_date   LEVEL - 1 AS day
         FROM   DUAL
         CONNECT BY t.start_date   LEVEL - 1 <= t.end_date
       ) d
WHERE  t.start_date <= t.end_date

Before Oracle 12, you can use:

SELECT t.id, d.COLUMN_VALUE AS day
FROM   table_name t
       CROSS JOIN TABLE(
         CAST(
           MULTISET(
             SELECT t.start_date   LEVEL - 1
             FROM   DUAL
             CONNECT BY t.start_date   LEVEL - 1 <= t.end_date
           )
           AS SYS.ODCIDATELIST
         )
       ) d
WHERE  t.start_date <= t.end_date

Or:

WITH dates (id, day, end_date) AS (
  SELECT id, start_date, end_date
  FROM   table_name
  WHERE  start_date <= end_date
UNION ALL
  SELECT id, day   1, end_date
  FROM   dates
  WHERE  day   1 <= end_date
)
SEARCH DEPTH FIRST BY id, day SET ord
SELECT id, day
FROM   dates;

Which, for the sample data:

CREATE TABLE table_name (id, start_date, end_date) AS
SELECT 1, DATE '2021-01-01', DATE '2022-03-22' FROM DUAL UNION ALL
SELECT 2, DATE '2022-01-01', DATE '2022-01-10' FROM DUAL;

All output:

ID DAY
1 01-JAN-21
1 02-JAN-21
... ...
1 21-MAR-22
1 22-MAR-22
2 01-JAN-22
2 02-JAN-22
... ...
2 09-JAN-22
2 10-JAN-22

db<>fiddle here

CodePudding user response:

One option might also be

SQL> WITH
  2     test (id, start_date, end_date)
  3     AS
  4        (SELECT 1, DATE '2020-01-01', DATE '2022-03-22' FROM DUAL)
  5      SELECT start_date   LEVEL - 1 datecolumn
  6        FROM test
  7  CONNECT BY LEVEL <= end_date - start_date   1
  8    ORDER BY datecolumn;

DATECOLUMN
----------
01.01.2020
02.01.2020
03.01.2020
04.01.2020
<snip>
14.03.2022
15.03.2022
16.03.2022
17.03.2022
18.03.2022
19.03.2022
20.03.2022
21.03.2022
22.03.2022

812 rows selected.

SQL>

If there - as MT0 commented - is more than a single row in that table that contains start/end dates, then

WITH
   test (id, start_date, end_date)
   AS
      (SELECT 1, DATE '2020-01-01', DATE '2022-03-22' FROM DUAL
       UNION ALL
       SELECT 2, DATE '2022-03-15', DATE '2022-03-23' FROM DUAL)
  SELECT id, start_date   COLUMN_VALUE - 1 datecolumn
    FROM test
         CROSS JOIN
         TABLE (
            CAST (
               MULTISET (    SELECT LEVEL
                               FROM DUAL
                         CONNECT BY LEVEL <= end_date - start_date   1)
                  AS SYS.odcinumberlist))
ORDER BY id, datecolumn;
  • Related