Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Aparna.

Asked: March 12, 2019 - 4:48 am UTC

Last updated: March 13, 2019 - 11:20 am UTC

Version: 11g

Viewed 1000+ times

You Asked

Hi All,

I have column ord which is common for all the records , then person_no. This can be repeated.
I have a column called flag which is a sequence. I was trying populate a new column(NEW_FLAG) which will basically rank the person_no according to the order it got populated (based on flag column)
Op should look like this

ORD PERSON_NO FLAG NEW_FLAG
2999362 21065699 1 1
2999362 21065699 2 1
2999362 12158176 3 2
2999362 10750089 4 3
2999362 5475332 5 4
2999362 11150508 6 5
2999362 5475332 7 4
2999362 3807718 8 6
2999362 3991003 9 7
2999362 3754090 10 8

Could you please help

with LiveSQL Test Case:

and Chris said...

Here's one way to approach this:

- Find the first flag value for each person using first_value
- Use this calculated first flag to rank() the results:
create table test_table (
  ord number, person_no number, flag number
);

insert into test_table values (2999362,3754090,10);
insert into test_table values (2999362,3807718,8);
insert into test_table values (2999362,3991003,9);
insert into test_table values (2999362,5475332,7);
insert into test_table values (2999362,5475332,5);
insert into test_table values (2999362 ,10750089,4);
insert into test_table values (2999362, 11150508,6);
insert into test_table values (2999362, 12158176,3);
insert into test_table values (2999362, 21065699,1);
insert into test_table values (2999362, 21065699,2);

commit;

with first_flags as (
  select t.*,
         first_value ( flag ) over ( 
           partition by person_no order by flag 
         ) fv_flag
  from   test_table t
)
  select ord, person_no,
         rank () over ( 
           order by fv_flag 
         ) rk
  from   first_flags
  order  by flag;

ORD       PERSON_NO   RK   
  2999362    21065699    1 
  2999362    21065699    1 
  2999362    12158176    3 
  2999362    10750089    4 
  2999362     5475332    5 
  2999362    11150508    7 
  2999362     5475332    5 
  2999362     3807718    8 
  2999362     3991003    9 
  2999362     3754090   10 

Rating

  (4 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

smooth

Racer I., March 12, 2019 - 10:56 am UTC

Hi,

rank()->dense_rank() to match OPs expected listing I guess.

regards,
Chris Saxon
March 12, 2019 - 1:21 pm UTC

Ah yes, I did have a dense_rank version... but copy-pasted the wrong query! ;)

Aparna s, March 12, 2019 - 10:57 am UTC

Thanks Chris,the output is slightly different from what i was looking for. I need the new flag in a sequence,no gap between numbers. I was looking for an output like below.

ORD PERSON_NO RK
2999362 21065699 1
2999362 21065699 1
2999362 12158176 2
2999362 10750089 3
2999362 5475332 4
2999362 11150508 5
2999362 5475332 4
2999362 3807718 6
2999362 3991003 7
2999362 3754090 8

Aparna s, March 12, 2019 - 11:03 am UTC

Thanks.. dense_rank worked perfectly..

using pattern matching

Rajeshwaran, Jeyabal, March 13, 2019 - 6:22 am UTC

Can this be done using pattern matching?

Tried but ended with this.
demo@PDB1> select *
  2  from t
  3  match_recognize(
  4    order by flag
  5    measures
  6      match_number() mno,
  7      classifier() cls
  8    all rows per match
  9    pattern (b1*)
 10    define
 11      b1 as person_no = prev(person_no) or
 12           count(*) = 1 )
 13  /

      FLAG        MNO CLS       ORD_ID  PERSON_NO
---------- ---------- ----- ---------- ----------
         1          1 B1       2999362   21065699
         2          1 B1       2999362   21065699
         3          2 B1       2999362   12158176
         4          3 B1       2999362   10750089
         5          4 B1       2999362    5475332
         6          5 B1       2999362   11150508
         7          6 B1       2999362    5475332
         8          7 B1       2999362    3807718
         9          8 B1       2999362    3991003
        10          9 B1       2999362    3754090

10 rows selected.

demo@PDB1>


dont find a way how flag = 5 and flag = 7 having same person_no to be clubbed together in pattern.

Chris Saxon
March 13, 2019 - 11:20 am UTC

I can't think of a way to do this in a single pass with pattern matching.

More to Explore

Analytics

Analytic SQL got you confused? Check out Connor McDonald's complete video course.