Search code examples
oracle-databasesql-update

Merge Update in duplicated rows oracle


I have a table with repeated rows but with the empty group_id field:

id reference1 group_id
1 AAAA
2 AAAA
3 AAAA
4 BBBB
5 BBBB
6 CCCC
7 CCCC
8 CCCC
9 CCCC
10 CCCC

I need to add a number to the group_id field as long as it is null and I use:

UPDATE journals_cv027_tab f1
   SET f1.group_id = journals_seq.nextval
 WHERE f1.group_id IS NULL
   AND EXISTS (SELECT reference1
                 FROM journals_cv027_tab c
                WHERE c.reference1 = f1.reference1);
COMMIT;    

This just added me a number for each record as follows:

id reference1 group_id
1 AAAA 1
2 AAAA 2
3 AAAA 3
4 BBBB 4
5 BBBB 5
6 CCCC 6
7 CCCC 7
8 CCCC 8
9 CCCC 9
10 CCCC 10

But I need to assign a number for each group of repeated records for example:

id reference1 group_id
1 AAAA 1
2 AAAA 1
3 AAAA 1
4 BBBB 2
5 BBBB 2
6 CCCC 3
7 CCCC 3
8 CCCC 3
9 CCCC 3
10 CCCC 3

Solution

  • I think no need a sequence based on your case, you rather can use DENSE_RANK() analytic function within a MERGE statment with MATCHED option, presumingly id is a primary key, which can easily be used within the matching condition of the subquery such as

    MERGE INTO journals_cv027_tab j1 
         USING 
         (SELECT j.*, 
                 DENSE_RANK() OVER (ORDER BY reference1) AS dr
            FROM journals_cv027_tab j) j2
              ON ( j2.id = j1.id )
          WHEN MATCHED THEN UPDATE SET j1.group_id = dr
         WHERE j1.group_id IS NULL
    

    Demo

    If you want to keep the value of the sequential number, then an option would be storing the max value for the group_id within a table which has one row and one column before truncating the table in order to use within the next update as <that value> + DENSE_RANK()...