Home » SQL & PL/SQL » SQL & PL/SQL » Need help on hierarchial query (Oracle 11.2.0.4, Linus)
Need help on hierarchial query [message #631978] Thu, 22 January 2015 10:37 Go to next message
sspn2010
Messages: 167
Registered: October 2008
Senior Member
Hi,

Could someone help me on the below query.

I've data as below (This table has 300M+ records in my actual table)


create table data_tbl as
with data_tbl as
-- Actual table
(select '1234' as old_cust_id, '3456' as new_cust_id, 'I' as status_code from dual
 union
 select '3456' as old_cust_id, '6789' as new_cust_id, 'I' as status_code from dual
 union
 select '6789' as old_cust_id, '6789' as new_cust_id, 'A' as status_code from dual
 union
 select '9089' as old_cust_id, '7842' as new_cust_id, 'I' as status_code from dual
 union
 select '7842' as old_cust_id, '8964' as new_cust_id, 'I' as status_code from dual
 union
 select '8964' as old_cust_id, '8964' as new_cust_id, 'A' as status_code from dual
 )
 select * from data_tbl;



Cust_id's can change over the time and keeping every occurance of update in the above table. My requirement is to update the new_cust_id field if the new_cust_id field changed to some other cust_id.

I've written below sql, but it's not returing the final new_cust_id.


-- Identify the customer records where the status of cust_id in new_cust_id is inactive (i.e. status_code = 'I') but didn't updated to most recent new_cust_id 
 -- FOr example cust_id 1234 changed to 3456 and cust_id 3456 changed to 6789 but didn't updated the new_cust_id to 6789 wherever new_cust_id is 3456

 create table upd_tbl as 
with upd_tbl as
(select a.old_cust_id, a.new_cust_id, b.status_code
    from data_tbl a, data_tbl b
   where a.new_cust_id = b.old_cust_id
       and b.status_code = 'I'
)
select * from upd_tbl;

1234	3456	I
9089	7842	I



Below recursive subquery is not returning the final new_cust_id. Let's say for the record with old_cust_id 1234 i need to return 6789 in new_cust_id field as it is the most recent cust_id for the cust_id 1234 (i.e. 1234 updated to 3456 and 3456 again updated to 6789, so i need to update new_cust_id to 6789 for the old_cust_id 1234)


WITH final_tbl (old_cust_id, new_cust_id, status_code, lvl)
     AS (SELECT old_cust_id,
                new_cust_id,
                status_code,
                1 AS lvl
           FROM upd_tbl
         UNION ALL
         SELECT b.new_cust_id,
                a.new_cust_id,
                a.status_code,
                b.lvl + 1
           FROM data_tbl a, final_tbl b
          WHERE b.new_cust_id = a.old_cust_id)
           SEARCH DEPTH FIRST BY old_cust_id SET SORTING
           CYCLE new_cust_id SET is_cycle TO 1 DEFAULT 0
  select old_cust_id, new_cust_id, status_code,lvl from final_tbl;

1234	3456	I	1
3456	6789	I	2
6789	6789	A	3
9089	7842	I	1
7842	8964	I	2
8964	8964	A	3



Appreciate your help!

Thanks
SS
Re: Need help on hierarchial query [message #631981 is a reply to message #631978] Thu, 22 January 2015 11:56 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Quote:
My requirement is to update the new_cust_id field if the new_cust_id field changed to some other cust_id.


What does this mean?

Quote:
Let's say for the record with old_cust_id 1234 i need to return 6789 in new_cust_id field as it is the most recent cust_id for the cust_id 1234


SQL> with data_tbl as
  2  -- Actual table
  3  (select '1234' as old_cust_id, '3456' as new_cust_id, 'I' as status_code from dual
  4   union
  5   select '3456' as old_cust_id, '6789' as new_cust_id, 'I' as status_code from dual
  6   union
  7   select '6789' as old_cust_id, '6789' as new_cust_id, 'A' as status_code from dual
  8   union
  9   select '9089' as old_cust_id, '7842' as new_cust_id, 'I' as status_code from dual
 10   union
 11   select '7842' as old_cust_id, '8964' as new_cust_id, 'I' as status_code from dual
 12   union
 13   select '8964' as old_cust_id, '8964' as new_cust_id, 'A' as status_code from dual
 14   )
 15  select old_cust_id, new_cust_id, status_code
 16  from data_tbl
 17  connect by prior new_cust_id = old_cust_id and prior status_code = 'I'
 18  start with old_cust_id = '1234' and status_code = 'I'
 19  /
OLD_ NEW_ S
---- ---- -
1234 3456 I
3456 6789 I
6789 6789 A

Re: Need help on hierarchial query [message #631982 is a reply to message #631981] Thu, 22 January 2015 12:42 Go to previous messageGo to next message
sspn2010
Messages: 167
Registered: October 2008
Senior Member
Hi Michael,

Thank you for your reply!

My requirement is if the cust_id (let's say A) is changed to new cust_id (cust_id B) and if the new cust_id (cust_id B) is again changed to different cust_id (cust_id C), then i need to update cust_id B to C in new_cust_id field wherever cust_id B exists. Hope this helps!

Thanks
Sri

Thanks
SS
Re: Need help on hierarchial query [message #631983 is a reply to message #631982] Thu, 22 January 2015 12:46 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

So to get the last modification, the current active one, just add "where status_code='A'" to my query but I correctly follow what you do, this is not just an update but also an insert you have to do to record the new modification.

Re: Need help on hierarchial query [message #631984 is a reply to message #631983] Thu, 22 January 2015 13:10 Go to previous messageGo to next message
sspn2010
Messages: 167
Registered: October 2008
Senior Member
Hi Michael,

Insert is being done by a separate process. After inserting data, i need to update the data. I added the condition you mentioned and added connect_by_root and got the results.

with data_tbl as
    -- Actual table
    (select '1234' as old_cust_id, '3456' as new_cust_id, 'I' as status_code from dual
     union
     select '3456' as old_cust_id, '6789' as new_cust_id, 'I' as status_code from dual
     union
     select '6789' as old_cust_id, '8712' as new_cust_id, 'I' as status_code from dual
     union
     select '8712' as old_cust_id, '8712' as new_cust_id, 'A' as status_code from dual
     union
     select '9089' as old_cust_id, '7842' as new_cust_id, 'I' as status_code from dual
    union
    select '7842' as old_cust_id, '8964' as new_cust_id, 'I' as status_code from dual
    union
    select '8964' as old_cust_id, '8964' as new_cust_id, 'A' as status_code from dual
    )
   select connect_by_root old_cust_id, new_cust_id, status_code
   from data_tbl where status_code = 'A'
   connect by prior new_cust_id = old_cust_id and prior status_code = 'I'
   start with status_code = 'I'


Thanks
SS
Re: Need help on hierarchial query [message #631985 is a reply to message #631984] Thu, 22 January 2015 13:11 Go to previous message
sspn2010
Messages: 167
Registered: October 2008
Senior Member
Forgot to attach results.


1234	8712	A
3456	8712	A
6789	8712	A
7842	8964	A
9089	8964	A



Thank you Michael for your help!

SS
Previous Topic: Need help on a query
Next Topic: Query on pagination Query
Goto Forum:
  


Current Time: Thu Apr 25 17:07:14 CDT 2024