Home » SQL & PL/SQL » SQL & PL/SQL » Use date field to determine matching field (11.2.0.1.0)
Use date field to determine matching field [message #629184] Thu, 04 December 2014 04:08 Go to next message
OraFerro
Messages: 433
Registered: July 2011
Senior Member
Hi All,

I am trying to rebuild a self reference field that was not used correctly.

Instead of using the primary key for self reference, another field (reference_no) was used. This field is not unique (its a user counter that resets every year).

I need to add a new field (REGISTRATION_REPLY_NO) and fill it with the correct reference but I need to write an update statement that updates REGISTRATION_REPLY_NO for each record by checking for all possible reference_no records (as the reference number can repeat) and get the registration_no for the record with a CREATE_DATE that is the first larger CREATE_DATE than the CREATE_DATE of the current record ).

case example:

CREATE TABLE TEST_DOCS
  (
  REGISTRATION_NO VARCHAR(10) PRIMARY KEY,
  TYPE NUMBER(1), --1 = INCOMING, 2 = REPLY
  REFERENCE_NO NUMBER(10),
  CREATE_DATE DATE,
  REPLY_NO NUMBER(10)
  );

INSERT ALL 
INTO TEST_DOCS VALUES ('2014-31201',1 ,820,TO_DATE('02-06-2013','DD-MM-YYYY'), 850 )
INTO TEST_DOCS VALUES ('2014-31206',2 ,850,TO_DATE('05-06-2013','DD-MM-YYYY'), NULL )
INTO TEST_DOCS VALUES ('2013-88201',1 ,320,TO_DATE('28-12-2013','DD-MM-YYYY'), 8 )
INTO TEST_DOCS VALUES ('2013-00006',2 ,8,TO_DATE('05-01-2013','DD-MM-YYYY'), NULL )
INTO TEST_DOCS VALUES ('2013-78201',1 ,1000,TO_DATE('25-12-2013','DD-MM-YYYY'), 8 )
INTO TEST_DOCS VALUES ('2014-00001',2 ,8,TO_DATE('02-01-2014','DD-MM-YYYY'), NULL )
SELECT * FROM DUAL;

ALTER TABLE TEST_DOCS ADD REGISTRATION_REPLY_NO VARCHAR(10);



Re: Use date field to determine matching field [message #629191 is a reply to message #629184] Thu, 04 December 2014 04:23 Go to previous messageGo to next message
Littlefoot
Messages: 21808
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
Quote:

get the registration_no for the record with a CREATE_DATE that is the first larger CREATE_DATE than the CREATE_DATE of the current record


That would be something like
select t.reference_no
from test_docs t
t.create_date = (select min(t2.create_date)                 -- the first CREATE_DATE ...
                 from test_docs t2
                 where t2.create_date > t.create_date       -- ... larger than the current record's CREATE_DATE
                   and t2.registration_no = t.registration_no
                )
Re: Use date field to determine matching field [message #629199 is a reply to message #629191] Thu, 04 December 2014 04:58 Go to previous messageGo to next message
OraFerro
Messages: 433
Registered: July 2011
Senior Member
Thanks Littlefoot, this example is similar to my trial but the problem is that the real table is large such a query takes very long time. I thought that there should be an idea instead of repeated table scans.

Thanks,
Ferro
Re: Use date field to determine matching field [message #629203 is a reply to message #629199] Thu, 04 December 2014 06:49 Go to previous messageGo to next message
OraFerro
Messages: 433
Registered: July 2011
Senior Member
Also just for the note, when you try the suggested query it does not produce any result because of the join field used:

select t.reference_no
from test_docs t
WHERE --added by Ferro
t.create_date = (select min(t2.create_date)                 -- the first CREATE_DATE ...
                 from test_docs t2
                 where t2.create_date > t.create_date       -- ... larger than the current record's CREATE_DATE
                   and t2.registration_no = t.registration_no
                )
Re: Use date field to determine matching field [message #629209 is a reply to message #629203] Thu, 04 December 2014 07:49 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
With LF's solution, if you now find the query having performance issues, then analyze the execution plan and create required index on create_date if required. You need to post more details if performance is really a concern. You can look at the sticky on top of performance tuning forum.
Re: Use date field to determine matching field [message #629217 is a reply to message #629209] Thu, 04 December 2014 08:28 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
Looks like you want analytics:
SQL> SELECT registration_no, TYPE, reference_no, create_date,
  2         LEAD(create_date) OVER(PARTITION BY reference_no ORDER BY create_date) AS next_date,
  3         LEAD(registration_no) OVER(PARTITION BY reference_no ORDER BY create_date) AS reply_registration_no
  4  FROM test_docs;
 
REGISTRATION_NO TYPE REFERENCE_NO CREATE_DATE NEXT_DATE   REPLY_REGISTRATION_NO
--------------- ---- ------------ ----------- ----------- ---------------------
2013-00006         2            8 05-Jan-2013 02-Jan-2014 2014-00001
2014-00001         2            8 02-Jan-2014             
2013-88201         1          320 28-Dec-2013             
2014-31201         1          820 02-Jun-2013             
2014-31206         2          850 05-Jun-2013             
2013-78201         1         1000 25-Dec-2013             
 
6 rows selected
 
SQL> 
Re: Use date field to determine matching field [message #629317 is a reply to message #629217] Sun, 07 December 2014 02:30 Go to previous messageGo to next message
OraFerro
Messages: 433
Registered: July 2011
Senior Member
Thanks Lalit and Cookiemonster,

My query looks like LittleFoot's (nested selects):

SELECT t1.registration_no, t1.TYPE, t1.reference_no, t1.reply_no, t1.create_date, 
  (
    select registration_no 
      from test_docs t2
      where t1.REPLY_NO = t2.REFERENCE_NO
      and t2.create_date = (
                            select min(t3.create_date)
                              from TEST_DOCS t3
                              where t3.REFERENCE_NO = t2.REFERENCE_NO
                              and t3.create_date >= t1.create_date
                            )
  ) My_Reply_ref_no
from test_docs t1;


However I did not manage to use Lead, or dense_rank to avoid the nesting levels. In Lead, I still need to add the condition where the reference_no of the partition is equal to the reply_no of the record.

Thanks,
Ferro
Re: Use date field to determine matching field [message #629335 is a reply to message #629317] Sun, 07 December 2014 22:28 Go to previous message
OraFerro
Messages: 433
Registered: July 2011
Senior Member
Hi All,

I would be thankful if anyone has a suggested enhancement on the select statement or an alternative using dense_rank or lead

Thanks,
Ferro
Previous Topic: UNPIVOT mutiple columns with different conditions
Next Topic: how to update values using trigger
Goto Forum:
  


Current Time: Thu Apr 25 13:49:38 CDT 2024