简体   繁体   中英

rank() and over () in oracle queries

I need to understand the difference between these two oracle queries specially between rank() over(order by length(cgp.group_name) desc) and rank() over(order by length(cgp.group_name), length(csc.subscriber_num) desc) ranking .

I searched on google regarding rank and understood below :

rank() over(order by length(cgp.group_name), length(csc.subscriber_num) desc) ranking : one ranking column will display in the result with values 1,2,3 according to the maximum match of group_name.

select csc.subscriber_num csc.group_id, 
       rank() over(order by length(cgp.group_name) desc) ranking  
from scallforward_info csc , 
     gprofile cgp 
where '0120111' like csc.subscriber_num||'%' 
  and   GROUP_NAME like 'TEST' ||'%' 
  and csc.account_number=99995555  
  and   csc.group_id= cgp.group_id  
  and csc.ver = 1 
  and cgp.ver = 1;


select csc.subscriber_num csc.group_id, 
       rank() over(order by length(cgp.group_name), length(csc.subscriber_num)  desc) ranking 
from scallforward_info csc , 
     gprofile cgp 
where '0120111' like csc.subscriber_num||'%' 
  and GROUP_NAME like 'TEST' ||'%' 
  and   csc.account_number=99995555  
  and csc.group_id= cgp.group_id  
  and   csc.ver = 1 
  and cgp.ver = 1;
rank() over(order by length(cgp.group_name) desc)

Will give each row a numeric rank in order of the length of the value in the cgp.group_name column in DESC order (longest-to-shortest) and will not try to break ties.

rank() over(order by length(cgp.group_name), length(csc.subscriber_num) desc)

Will give each row a numeric rank in order of the length of the value in the cgp.group_name column in ASC order (shortest-to-longest) and will try to break ties using the length of the value in the csc.subscriber_num in DESC order (longest-to-shortest).

To see the difference, here's a query that runs against some sample data (if you aren't aware of sub-query factoring (aka "the with clause" aka common table expressions aka CTE), then I highly recommend that you research it!):

with sample_data as (select 1 id, 1 val1, 1 val2, 13 val3 from dual union all
                     select 2 id, 1 val1, 2 val2, 12 val3 from dual union all
                     select 3 id, 1 val1, 3 val2, 11 val3 from dual union all
                     select 4 id, 1 val1, 4 val2, 10 val3 from dual union all
                     select 5 id, 2 val1, 4 val2, 9 val3 from dual union all
                     select 6 id, 2 val1, 3 val2, 8 val3 from dual union all
                     select 7 id, 2 val1, 2 val2, 7 val3 from dual union all
                     select 8 id, 2 val1, 1 val2, 6 val3 from dual union all
                     select 9 id, 3 val1, 2 val2, 5 val3 from dual union all
                     select 10 id, 3 val1, 6 val2, 4 val3 from dual union all
                     select 11 id, 3 val1, 2 val2, 3 val3 from dual union all
                     select 12 id, 4 val1, 7 val2, 2 val3 from dual union all
                     select 13 id, 4 val1, 8 val2, 1 val3 from dual)
select id,
       val1,
       val2,
       val3,
       rank() over (order by val1) rank1,
       rank() over (order by val1, val2) rank2,
       dense_rank() over (order by val1) dense_rank1,
       dense_rank() over (order by val1, val2) dense_rank2
from   sample_data;


        ID       VAL1       VAL2       VAL3      RANK1      RANK2 DENSE_RANK1 DENSE_RANK2
---------- ---------- ---------- ---------- ---------- ---------- ----------- -----------
         1          1          1         13          1          1           1           1
         2          1          2         12          1          2           1           2
         3          1          3         11          1          3           1           3
         4          1          4         10          1          4           1           4
         8          2          1          6          5          5           2           5
         7          2          2          7          5          6           2           6
         6          2          3          8          5          7           2           7
         5          2          4          9          5          8           2           8
         9          3          2          5          9          9           3           9
        11          3          2          3          9          9           3           9
        10          3          6          4          9         11           3          10
        12          4          7          2         12         12           4          11
        13          4          8          1         12         13           4          12

Also, as per the documentation :

Rows with equal values for the ranking criteria receive the same rank.

Couple the two together and hopefully you can see that because you have rows that share the same values across all the columns in the order by clause, they have the same rank value.

Eg In the above query's result, rows with id in (1,2,3,4) all have a rank1 of 1, whereas ids 9 and 11 have the same rank2, but id 10 has a different rank) So, the more specific your ranking criteria, the less likely you are to receive ties (in general).

Does that answer your question? I've also included the equivalent DENSE_RANK functions in the query above, so you can see the difference in the rank numbering.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM