hajduk
hajduk

Reputation: 121

Updating previous year values

I have a table T like this:

ID|DESC1_ID | DESC2_ID | TS     | CUM_MONTH_PREV_YEAR| CUM_MONTH_THIS_YEAR|ID2
--------------------------------------------------------------------------|-
1 |1        |1         |31.01.22|                    | 220                |1
----------------------------------------------------------------------------
2 |1        |2         |31.01.22|                    | 500                |1
---------------------------------------------------------------------------
3 |1        |3         |31.01.22|                    | 22                 |1
----------------------------------------------------------------------------
4 |2        |1         |31.01.22|                    | 50                 |1
---------------------------------------------------------------------------
5 |1        |1         |01.02.23|                    | 230                |2
----------------------------------------------------------------------------
6 |1        |2         |01.02.23|                    | 300                |2
---------------------------------------------------------------------------
7 |1        |3         |01.02.23|                    | 32                 |2
----------------------------------------------------------------------------
8 |2        |1         |01.02.23|                    | 30                 |2 

I wish to update the field CUM_MONTH_PREV_YEAR for all entries where id2 is 2. The value should be a previous year value. It could happen, that the date(TS) is not exactly from 1 year before. I have a query below which does what I want.

UPDATE T t1  
    SET CUM_MONTH_PREV_YEAR = (SELECT NVL(CUM_MONTH_THIS_YEAR , 0)
                                FROM T t2
                              WHERE t2.TS = (SELECT MAX(TS) 
                                             FROM T
                                             WHERE TS BETWEEN  ADD_MONTHS( t1.TS - 7, -12) AND ADD_MONTHS( t1.TS, -12)
                                             AND DESC1_ID = t1.DESC1_ID
                                             AND DESC2_ID = t1.DESC2_ID )
                            AND t2.DESC1_ID = t.DESC1_ID
                            AND t2.DESC2_ID = t.DESC2_ID )  
WHERE ID2 = 2 ;

I wanted to ask if there is a better way to reach the goal.

UPDATE:

As everything is simplified it happened only by the coincidence that ID2 for previous year is 1 and for this year is 2. In the reality there are much more values.

UPDATE: The values are stored daily(on working days).

Upvotes: 0

Views: 90

Answers (2)

d r
d r

Reputation: 7766

UPDATED ANSWER
works on daily bases even if some dates don't exist in previous year. In that case the first date before that is fetched.

UPDATE A_TBL t
SET t.CUM_MONTH_PREV_YEAR = (  Select PREV_CUM  
                               From ( SELECT      t.DESC1_ID, t.DESC2_ID, MAX(t.TS) "TS", MAX(t.CUM_MONTH_THIS_YEAR) "PREV_CUM"
                                      FROM        A_TBL t
                                      INNER JOIN  A_TBL t2 ON(t2.DESC1_ID = t.DESC1_ID And t2.DESC2_ID = t.DESC2_ID)
                                      WHERE       To_Number(To_Char(t.TS, 'yyyymmdd')) <= To_Number(To_Char(ADD_MONTHS(t2.TS, -12), 'yyyymmdd'))
                                      GROUP BY    t.DESC1_ID, t.DESC2_ID 
                                    )
                              Where DESC1_ID = t.DESC1_ID And DESC2_ID = t.DESC2_ID  )
WHERE t.ID2 = 2;

All that you need is the innermost query which gives you the data from the same date or first one before in previous year of that in row with ID2 = 2 (one beeing updated). This is the query:

SELECT      t.DESC1_ID, t.DESC2_ID, MAX(t.TS) "TS", MAX(t.CUM_MONTH_THIS_YEAR) "PREV_CUM"
FROM        A_TBL t
INNER JOIN  A_TBL t2 ON(t2.DESC1_ID = t.DESC1_ID And t2.DESC2_ID = t.DESC2_ID)
WHERE       To_Number(To_Char(t.TS, 'yyyymmdd')) <= To_Number(To_Char(ADD_MONTHS(t2.TS, -12), 'yyyymmdd'))
GROUP BY    t.DESC1_ID, t.DESC2_ID 

  DESC1_ID   DESC2_ID TS          PREV_CUM
---------- ---------- --------- ----------
         2          1 31-JAN-22         50 
         1          2 31-JAN-22        500 
         1          3 31-JAN-22         22 
         1          1 31-JAN-22        220

The result after the update is:

Select * From A_TBL;
ID DESC1_ID DESC2_ID TS CUM_MONTH_PREV_YEAR CUM_MONTH_THIS_YEAR ID2
1 1 1 31-JAN-22 220 1
2 1 2 31-JAN-22 500 1
3 1 3 31-JAN-22 22 1
4 2 1 31-JAN-22 50 1
5 1 1 01-FEB-23 220 230 2
6 1 2 01-FEB-23 500 300 2
7 1 3 01-FEB-23 22 32 2
8 2 1 01-FEB-23 50 30 2

Upvotes: 1

gotqn
gotqn

Reputation: 43626

Looking at your data, I think you are looking for this:

UPDATE table_name A
SET CUM_MONTH_PREV_YEAR = (SELECT B.CUM_MONTH_THIS_YEAR
                           FROM table_name B
                           WHERE A.id2 - 1 = B.id2
                             AND A.DESC1_ID = B.DESC1_ID
                             AND A.DESC2_ID = B.DESC2_ID);
                             
 SELECT *
 FROM table_name;    

enter image description here

Upvotes: 1

Related Questions