Home > Enterprise >  How to increase date by 1 month in Oracle sql
How to increase date by 1 month in Oracle sql

Time:01-22

I want to add 1 month for loop by subscribed month to get each customers monthly payment date.

I have a table like this:

ID REGISTER DATE SUBSCRIBED MONTH
1 2022.01.01 3
2 2022.07.01 6

I want to have result like this:

ID REGISTER DATE SUBSCRIBED MONTH MUST PAY DATE
1 2022.01.01 3 2022.01.01
1 2022.01.01 3 2022.02.01
1 2022.01.01 3 2022.03.01
2 2022.07.01 6 2022.07.01
2 2022.07.01 6 2022.08.01
2 2022.07.01 6 2022.09.01
2 2022.07.01 6 2022.10.01
2 2022.07.01 6 2022.11.01
2 2022.07.01 6 2022.12.01

Tried this, but returning duplicated.

SELECT ID, ADDMONTHS(REGISTER_DATE,LEVEL) FROM SUBLIST CONNECT BY LEVEL<=SUB_MONTH

Any help will be appreciated. Many thanks.

CodePudding user response:

Here's one option:

Setting date format (you don't have to do that):

SQL> alter session set nls_date_format = 'yyyy.mm.dd';

Session altered.

Sample data:

SQL> with test (id, register_date, subscribed_month) as
  2    (select 1, date '2022-01-01', 3 from dual union all
  3     select 2, date '2022-07-01', 6 from dual
  4    )

Query begins here:

  5  select id, register_date, subscribed_month,
  6    add_months(register_date, column_value - 1) must_pay_date
  7  from test cross join table(cast(multiset(select level from dual
  8                                           connect by level <= subscribed_month
  9                                          ) as sys.odcinumberlist))
 10  order by id, register_date, must_pay_date;

        ID REGISTER_D SUBSCRIBED_MONTH MUST_PAY_D
---------- ---------- ---------------- ----------
         1 2022.01.01                3 2022.01.01
         1 2022.01.01                3 2022.02.01
         1 2022.01.01                3 2022.03.01
         2 2022.07.01                6 2022.07.01
         2 2022.07.01                6 2022.08.01
         2 2022.07.01                6 2022.09.01
         2 2022.07.01                6 2022.10.01
         2 2022.07.01                6 2022.11.01
         2 2022.07.01                6 2022.12.01

9 rows selected.

SQL>

CodePudding user response:

You can inner join your data to a subquery containing rows with numbers of months to be added:

WITH
    tbl (ID, REGISTER_DATE, SUBSCRIBED_MONTH) AS
        (
            Select 1, DATE '2022-01-01', 3 From Dual Union All
            Select 2, DATE '2022-07-01', 6 From Dual
        )
SELECT      t0.ID, t0.REGISTER_DATE, t0.SUBSCRIBED_MONTH,
            Add_Months(t0.REGISTER_DATE, t1.MNTHS - 1) "PAY_DATE",
            t1.MNTHS "PAYMENT_NO"
FROM        tbl t0
INNER JOIN  ( Select DISTINCT ID, LEVEL "MNTHS" From tbl Connect By LEVEL <= SUBSCRIBED_MONTH ) t1 ON(t1.ID = t0.ID)
ORDER BY    t0.ID, t0.REGISTER_DATE, t1.MNTHS

Which with your sample data

WITH
    tbl (ID, REGISTER_DATE, SUBSCRIBED_MONTH) AS
        (
            Select 1, DATE '2022-01-01', 3 From Dual Union All
            Select 2, DATE '2022-07-01', 6 From Dual
        )

... results as ...

        ID REGISTER_DATE SUBSCRIBED_MONTH PAY_DATE  PAYMENT_NO
---------- ------------- ---------------- --------- ----------
         1 01-JAN-22                    3 01-JAN-22          1 
         1 01-JAN-22                    3 01-FEB-22          2 
         1 01-JAN-22                    3 01-MAR-22          3 
         2 01-JUL-22                    6 01-JUL-22          1 
         2 01-JUL-22                    6 01-AUG-22          2 
         2 01-JUL-22                    6 01-SEP-22          3 
         2 01-JUL-22                    6 01-OCT-22          4 
         2 01-JUL-22                    6 01-NOV-22          5 
         2 01-JUL-22                    6 01-DEC-22          6  
  • Related