There are several ways to rank records based on certain variables. One of the is to use row_number
select * from TBL_TEST order by grp, num;
GRP NUM
---------- ----------
A 1
A 2
A 2
A 3
A 4
B 1
B 2
B 4
B 5
Row_number() generates unique sequece numbers without gap. Ties are given different numbers. I use row_number() to generate unique id.
Example 1. generate rank separately for GRP
with tbl as(
select a.grp, a.num, row_number() over(partition by GRP order by num) rnk from TBL_TEST a)
select * from tbl order by grp, rnk ;
GRP NUM RNK
---------- ---------- ----------
A 1 1
A 2 2
A 2 3
A 3 4
A 4 5
B 1 1
B 2 2
B 4 3
B 5 4
Example 2. Generate rank without partition by GRP
with tbl as(
select a.grp, a.num, row_number() over(order by grp, num) rnk from TBL_TEST a)
select * from tbl order by grp, rnk ;
GRP NUM RNK
---------- ---------- ----------
A 1 1
A 2 2
A 2 3
A 3 4
A 4 5
B 1 6
B 2 7
B 4 8
B 5 9
I will discuss rank functions including dense_rank(), ran() in another post.
Popular Topics
Popular Topics
Showing posts with label rank. Show all posts
Showing posts with label rank. Show all posts
Thursday, August 02, 2012
Tuesday, June 05, 2012
SAS proc rank and its Oracle SQL equivalent
The following SAS rank and Oracle SQL produce the same results. In SAS, when there are ties, the average rank is used. To do the same in Oracle, we calculate the unique row numbers and then its average based on group id and variable (amt).
SAS rank.
proc rank data=tbl_in out=tbl_out ties=mean descending;
by grp;
var amt;
ranks amt_rnk;
run;
Oracle SQL rank.
create table tbl_out
as with tbl as
(
select a.*,
row_number() over(partition by grp order by amt desc) amt_rnk0 from tbl_in a
) select a.*, (avg( amt_rnk0 ) over(partition by grp, amt )) amt_rnk
from tbl a;
Sunday, May 27, 2012
Remove Duplicates From Data
It is quite common to have duplicates in the data. From example, an application is submitted or a claim is filed multiple times. With Oracle function row_number function, we can easily remove the duplicates.
The following SQL first calculates the rank of records by app_date for each app_id, then it only selects those records with ranks equals 1. The only earliest record for each app_id will be selected.
with tbl as
(
select a.*,
row_number() over(partition by app_id order by APP_DATE ) rnk from CELL_PHONE_SERVICE_APPS a
)
select * from tbl where rnk=1;
If we want to keep the latest record for each app_id, we simply generate rank for each app_id by the descending order of app_date as shown below.
with tbl as
(
select a.*,
row_number() over(partition by app_id order by APP_DATE desc ) rnk from CELL_PHONE_SERVICE_APPS a
)
select * from tbl where rnk=1;
Subscribe to:
Posts (Atom)