RANKING FUNCTIONS

The popularity of window functions is only rivaled by their usefulness. This is especially true for the subset of window functions commonly referred to as ranking functions. I’ll first introduce the why behind ranking functions and then dive into the how and when. The how walks through calculating rank using SQL to meet a common reporting requirement while the when explores scenarios for each specific ranking function. At the end of this page, I’ll briefly comment on why it is important to provide proper context to your audience around ranking outcomes. The schemas, corresponding tables, and data used to support the examples on this page can be found at livesql.oracle.com.

Why Ranking Functions?
A number by itself is arguably meaningless, so we give life to numbers by providing context. We have a propensity for using numbers to describe things in terms of relative size, importance, and position. To illustrate, consider the following statements regarding the data displayed in the table below: sales representative 161 is the number one sales representative, the top three performers, located in rows two through four, are sales representatives 161, 156, and 154, and the bottom three performers, located in rows seven through nine, are 163, 153, and 160.

sales_rep_idtotal_sales
161661734.5
156202617.6
154171973.1
158156296.2
159151167.2
155134415.2
163128249.5
153114215.7
16088238.4

Associating each sales representative’s performance with an integer value is easy, natural, and at the same time, powerful. By doing so, we can quickly convey how great or poor each sales representative’s performance is relative to other sales representatives’ performances. This is the concept of rank, and it is usually done based on some specification or set of instructions. For clarity, see the augmented table below where the rank value associated with each sales representative is based on the corresponding total sales value. The largest total sales value has a corresponding rank of 1, second largest total sales value a rank value of 2, and so on.

sales_rep_idtotal_salesperformance_rank
161661734.51
156202617.62
154171973.13
158156296.24
159151167.25
155134415.26
163128249.57
153114215.78
16088238.49

The integer value we associate with each performance can also be used to convey position or location. For example, we can refer to an observation simply by the row number. Stating, “the performance of sales representative 163 can be found in row 8” allows the consumer of the data to quickly navigate their eyes to this location within the data.

Calculating Rank Using SQL
Modern relational database management systems (RDBMS) allow us to incorporate the ideas of rank and location using window or analytic functions. The specific window functions used to do so are RANK, DENSE_RANK, and ROW_NUMBER. These window functions are shared across most flavors of SQL and are somewhat straightforward to use after a brief introduction on the syntax and clauses. If you’re unfamiliar with the syntax and individual clauses for window functions, then consider reading my brief explanation here before continuing further.

The ranking functions have significant overlap in terms of the SQL code using to implement them; however, the outcome when used against the same data can differ significantly. Let’s walk through a concrete example to better understand the similarity and differences across ranking functions.

Suppose we are given the task of generating a report containing the product ID, product name, category ID, and list price for each product. In addition to these attributes, we are also required to rank each of the products, in descending order, based on their list prices. This is where this seemingly simple task can result in generating an erroneous report. In the absence of details concerning the treatment of ties (i.e., multiple products with the same list price), any of the three ranking functions could be used. Let’s dive into this further.

In the result set below, notice the integer values returned by each function, ROW_NUMBER, RANK, and DENSE_RANK are identical up until the 13th product listed. The difference observed in rows 12 and 13 is attributable to the products having the same list price value of 999. The ROW_NUMBER function assigns consecutive integer values without addressing ties while RANK and DENSE_RANK functions do address ties. RANK assigns the same integer value to the rows with the same list price value and determines the next row’s integer value (i.e., rank) by adding the number of tied rows to the previous or tied rank value. In this case, there are only two rows with the same list price value associated with rank 12, so the rank value assigned to the row following the tie is 14 (i.e., 12 + 2). DENSE_RANK also addresses ties by assigning the tied rows the same rank value; however, the function doesn’t incorporate the same gaps in rank values. Instead, DENSE_RANK assigns the row immediately following a tie the subsequent rank value. Notice, the sequence is 12, 12, 13 where the RANK function assigned the integer values, 12, 12, 14 for the same rows.

product_idproduct_namecategory_idlist_pricerow_numberrankdense_rank
2779Desk – OS/O/F313980111
3003Laptop 128/12/56/v90/110193219222
2351Desk – W/48/R312900333
3004Laptop 64/10/56/220192768444
3001Laptop 48/10/56/110192556555
2231Desk – S/V312510666
2350Desk – W/48312500777
3000Laptop 32/10/56191749888
1822SPNIX4.0 – SL241500999
3064Monitor 21/SD111023101010
1799SPNIX3.3 – SL241000111111
3065Monitor 21/D11999121212
2999Laptop 16/8/11019999131212
2236Plasma Monitor 10/TFT/XGA11964141413
2252Monitor 21/HR/M11889151514
3331Monitor 21/HR11879161615
2382HD 18.2GB@10000 /I13850171716
3399HD 18GB /SE13815181817
1743HD 18.2GB @10000 /E13800191918
3337Mobile Web Phone31800201918
2255HD 12GB @7200 /SE13775212119
3350Plasma Monitor 10/LE/VGA11740222220
2459LaserPro 1200/8/BW12699232321
1750DIMM – 2GB14699242321
3071HD 12GB /S13633252522
3334HD 12GB /R13612262623
3054Plasma Monitor 10/XGA11600272724
2384DIMM – 1GB14599282825
3072HD 12GB /N13567292926
3501C for SPNIX4.0 – Sys25555303027
3354HD 12GB /I13543313128
2245Monitor 19/SD/M11512323229
2471SPNIX3.3 SU24500333330
3061Monitor 19/SD11499343431
3127LaserPro 600/6/BW12498353532
1948Envoy IC/5819498363532
3353HD 10GB /R13489373733
2879Router – ASR/3W19456383834
1772HD 9.1GB @1000013456393834
2414HD 9.1GB @10000 /I13454404035
2254HD 10GB /I13453414136
1780C for SPNIX3.3 – Sys25450424237
3020Envoy IC19449434338
2400DIMM – 512 MB14448444439
3069HD 10GB /S13436454540
2497WSP DA-29015399464641
2253HD 10GB @5400 /SE13399474641
2257HD 8GB /I13399484641
3400HD 8GB /SE13389494942
3057Monitor 17/SD11369505043
2415HD 9.1GB @720013359515144
2410HD 8.4GB @540013357525245
2243Monitor 17/HR/F11350535346
1797Inkjet C/8/HQ12349545447
2878Router – ASR/2W19345555548
1768HD 8.2GB @540013345565548
1749DIMM – 256MB14337575749
2266DVD 12x17333585850
2378DIMM – 128 MB14305595951
2337Business Cards – 1000/2L32300606052
1739SDRAM – 128 MB14299616153
3060Monitor 17/HR11299626153
2496WSP DA-13015299636153
3091VRAM – 64 MB14279646454
1791Industrial 700/HD12275656555
3077DVD 8x17274666656
2276SDRAM – 48 MB14269676757
1726LCD Monitor 11/PM11259686858
3088SDRAM – 32 MB14258696959
2359LCD Monitor 9/PM11249707060
1763DIMM – 64MB14247717161
1781CDW 20/48/E17233727262
2152Router – DTMF419231737363
1792Industrial 600/DQ12225747464
3073HD 6GB /I13224757565
240664MB Cache /M14223767666
2264CDW 20/48/I17223777666
3248Smart Suite – S4.0/DE29222787867
3246Smart Suite – S4.0/SP29222797867
3253Smart Suite – S4.0/EN29222807867
3245Smart Suite – S4.0/FR29222817867
240464MB Cache /NM14221828268
2424CDW 12/2417221838268
3086VRAM – 16 MB14211848469
2409TD 7GB/817210858570
2537Business Cards Box – 100032200868671
2453Inkjet C/412195878772
3090RAM – 48 MB14193888873
2396EDO – 32MB14179898974
1788CPU D60015178909075
2430Compact 400/LQ12175919176
3170Smart Suite – V/SP29161929277
2274RAM – 32 MB14161939277
2422SPNIX4.0 – SAL24150949478
2302Inkjet B/612150959478
3171Smart Suite – S3.3/EN29148969679
2371C for SPNIX4.0 – Doc25146979780
2638Envoy DS/E19137989881
2272RAM – 16 MB14135999982
1740TD 12GB/DAT1713410010083
1761CD-ROM 600/I/32x1713410110083
2394DIMM – 32MB1412810210284
1794OSI 8-16/IL2912810310284
1779C for SPNIX3.3 – Doc2512810410284
2402CD-ROM 600/E/24x1712710510585
3204Envoy DS1912610610686
2986Manual – Vision OS/2x +3312510710787
1782Compact 400/DQ1212510810787
3087DIMM – 16 MB1412410910988
239532MB Cache /M1412311011089
2439CPU D4001512311111089
175532MB Cache /NM1412111211290
3247Smart Suite – V/DE2912011311391
3176Smart Suite – V/EN2912011411391
3177Smart Suite – V/FR2912011511391
2403CD-ROM 600/I/24x1711711611692
2005IC Browser Doc – S2911511711793
2722PC Bag – L/D3911211811894
3359SDRAM – 16 MB1411111911995
1774Base ISO CP – BL2911012012096
3502C for SPNIX3.3 -Sys/U2510512112197
3114MB – S900/650+1510112212298
1742CD-ROM 500/16x1710112312298
1787CPU D3001510112412298
2452SPNIX4.0 – DL2410012512599
2335Mobile phone3110012612599
1801SPNIX3.3 – AL2410012712599
3362Web Browser – SB/S 4.02999128128100
2381CD-ROM 8x1799129128100
2293MB – S6001599130128100
2262ZIP 1001798131131101
2411GP 1280×10241598132131101
24128MB EDO Memory1498133131101
2377PS 110V HS/US1997134134102
2311PS 220V /L1995135135103
2370PS 220V /HS/FR1991136136104
2004IC Browser – S2990137137105
1733PS 220V /UK1989138138106
2752MB – S5501588139139107
2721PC Bag – L/S3987140140108
1738PS 110V /US1986141141109
3173Graphics – SA2986142141109
3391PS 110/2201985143143110
3124PS 110V /T1984144144111
2423C for SPNIX4.0 – 1 Seat2584145144111
2449OSI 1-4/IL2983146146112
2387PS 220V /FR1983147146112
1748PS 220V /EUR1983148146112
3082Modem – 56/90/E1781149149113
3123PS 220V /D1981150149113
3258Web Browser – SB/V 1.02980151151114
2536Business Cards – 250/2L3280152151114
2470SPNIX4.0 – NL2480153151114
2462SPNIX4.0 – UL/N2480154151114
2467SPNIX4.0 – UL/D2480155151114
1729Chemicals – RCP3980156151114
2365Chemicals – TCS3978157157115
3108KB E/EN1678158157115
2375GP 1024×7681578159157115
3112MB – S5001577160160116
2268Modem – 56/H/E1777161160116
2299PS 12V /P1976162162117
2468SPNIX4.0 – UL/C2475163163118
3101IC Browser – V2975164163118
2419Battery Backup (DA-290)1972165165119
2340Chemicals – SW3972166165119
2464SPNIX4.0 – UL/A2470167167120
2995SPNIX3.3 SAU2470168167120
3083Modem – 56/H/I1767169169121
2260DFD 1.44/3.51767170169121
3257Web Browser – SB/S 2.12966171171122
2751MB – S4501566172171122
2270Modem – 56/90/I1766173171122
3290SPNIX3.3 DU2465174174123
2374Modem – C/1001765175174123
1804SPNIX3.3 – UL/N2465176174123
3182Word Processing – SWP/V 4.52265177174123
2782PC Bag – C/S3962178178124
1778C for SPNIX3.3 – 1 Seat2562179178124
2418Battery Backup (DA-130)1961180180125
1803SPNIX3.3 – DL2460181181126
2308Video Card /E321558182182127
2336Business Cards Box – 2503255183183128
3167Manual – Vision OS/2.x3355184183128
2049MB – S3001555185183128
1820SPNIX3.3 – NL2455186183128
2278Battery – NiHM1955187183128
1808SPNIX3.3 – UL/D2455188183128
2976Drive Mount – D1952189189129
3179Spreadsheet – SSS/S 2.12150190190130
3183Word Processing – SWS/V 4.52250191190130
1806SPNIX3.3 – UL/C2450192190130
3262Spreadsheet – SSS/S 2.22150193190130
1805SPNIX3.3 – UL/A2450194190130
3260Word Processing – SWP/S 4.42250195190130
3155Monitor Hinge – HD1149196196131
1769GP 800×6001548197197132
3133Video Card /321548198197132
3110KB 101/FR1648199197132
2289KB 101/ES1648200197132
3106KB 101/EN1648201197132
3225Card Organizer – 10003247202202133
3129Sound Card STD1546203203134
3220Manual – Vision OS/1.23345204204135
2492SPNIX3.3 AU2445205204135
3197Spreadsheet – SSS/V 2.12145206204135
3178Spreadsheet – SSP/V 2.02145207204135
2982Drive Mount – A1944208208136
2522Battery – EL1944209208136
2261FD 1.44/3.5/E1742210210137
3172Graphics – DIK+2942211210137
3117Mouse C/E1641212212138
2416Client ISO CP – S2941213212138
3165Manual – Vision Tools2.03340214214139
3361Spreadsheet – SSP/S 1.52140215214139
3256Spreadsheet – SSS/V 2.02140216214139
2259FD 1.44/3.51739217217140
3234Monitor Hinge – STD1139218217140
3175Project Management – S4.02937219219141
3277Drive Mount – A/T1936220220142
3255Spreadsheet – SSS/CD 2.2B2135221221143
3163Manual – Vision Net6.3/US3335222221143
2417Client ISO CP – V2933223223144
3224Card Organizer – 2503232224224145
3251Project Management – V2931225225146
3216Manual – Vision Net6.33330226226147
3250Graphics – DIK2928227227148
2761Mouse +WP/CL1627228228149
1775Client ISO CP – S2927229228149
3252Project Management – S3.32926230230150
2493SPNIX3.3 C/DU2425231231151
2494SPNIX3.3 NU2425232231151
2319Screws <Z.24.S>1925233231151
2339Paper – Std Printer3225234231151
1825X25 – 1 Line License2925235231151
3140Screws <Z.16.S>1924236236152
3300Screws <S.32.P>1923237237153
2058Mouse +WP1623238237153
2322Screws <Z.28.P>1923239237153
2316Screws <S.32.S>1922240240154
3503C for SPNIX3.3 – Seat/U2522241240154
3139Screws <S.16.S>1921242242155
2144Card Organizer Cover3218243243156
1940ESD Bracelet/Clip3918244243156
3150Card Holder – 253218245243156
3134Screws <B.32.S>1918246243156
2323Screws <B.32.P>1918247243156
3143Screws <B.28.S>1916248248157
1912SS Stock – 3mm3915249249158
2631ESD Bracelet/QR3915250249158
3301Screws <B.28.P>1915251249158
1910FG Stock – H3914252252159
3209Sharpener – Pencil3213253253160
2596SS Stock – 1mm3912254254161
2030Latex Gloves3912255254161
3051Pens – 10/MP3212256254161
2783Clips – Paper3210257257162
2594FG Stock – L399258258163
3511Paper – HQ Printer329259258163
1745Cable SCSI 20/WD->D199260258163
2093Pens – 10/FP328261261164
2056Mouse Pad /CL168262261164
1737Cable SCSI 10/FW/ADS198263261164
2373Cable RS232 10/AF196264264165
2810Inkvisible Pens326265264165
2380Cable PR/15/P196266264165
1734Cable RS232 10/AM196267264165
2870Pencil – Mech325268268166
2457Cable PR/S/6195269268166
2725Machine Oil394270270167
2408Cable PR/P/6194271270167
2334Resin394272270167
3099Cable Harness194273270167
2211Wrist Pad164274270167
3097Cable Connector – 32R193275275168
3193Plastic Stock – W/HD393276275168
3187Plastic Stock – B/HD393277275168
2944Wrist Pad /CL163278275168
3515Lead Replacement322279279169
3189Plastic Stock – G392280279169
2330Plastic Stock – R392281279169
2326Plastic Stock – Y392282279169
3208Pencils – Wood322283279169
3191Plastic Stock – O392284279169
2091Paper Tablet LW 8 1/2 x 11321285285170
2808Paper Tablet LY 8 1/2 x 11321286285170
SELECT
	oe.product_information.product_id,
    oe.product_information.product_name,
    oe.product_information.category_id,
    oe.product_information.list_price,
    ROW_NUMBER() OVER (
        ORDER BY oe.product_information.list_price DESC
    ) AS row_number,
    RANK() OVER (
        ORDER BY oe.product_information.list_price DESC
    ) AS rank,
    DENSE_RANK() OVER (
        ORDER BY oe.product_information.list_price DESC
    ) AS dense_rank
FROM
	oe.product_information
WHERE
    oe.product_information.list_price IS NOT NULL
ORDER BY
    list_price DESC;

Function Choice
The result set and corresponding SQL code above highlight, at a high level, the similarities and differences among the ranking functions; however, when solving real world problems, you will need to know more than the overlap in syntax and the differences in the rank calculations. You will need to choose the right function for the task at hand.

Is the function being used to assign integer values to each row for reference purposes (e.g., “The sale in question is in row 23.”) or to implement a ranking system (e.g., sales representatives ranked by total sales, descending)? If it is the former of the two, then use the ROW_NUMBER function. If it is the latter of the two, then a conscious choice between the use of RANK and DENSE_RANK is required.

When choosing between the two functions, it is important to consider the impact ties have on the intended message and the overall consequences. For example, imagine annual bonuses at a company are rewarded to product owners with products ranked within the top 5 in terms of distinct purchases. Given the data below, six products are in the top 5 when RANK is used while eight are in the top 5 when DENSE_RANK is used. Choosing one method over another will result in more or less product owners being rewarded an annual bonus.

product_idproduct_namedistinct_purchasesrankdense_rank
3106KB 101/EN2111
3143Screws <B.28.S>1822
3127LaserPro 600/6/BW1733
3150Card Holder – 251644
3155Monitor Hinge – HD1644
3123PS 220V /D1644
2289KB 101/ES1575
3117Mouse C/E1575
2311PS 220V /L1496
3163Manual – Vision Net6.3/US1496
3133Video Card /3213117
2299PS 12V /P12128
3114MB – S900/650+11139
3139Screws <S.16.S>11139
3165Manual – Vision Tools2.011139
2326Plastic Stock – Y11139
2316Screws <S.32.S>101710
2308Video Card /E32101710
2293MB – S600101710
2330Plastic Stock – R92011
2334Resin92011
3129Sound Card STD92011
3108KB E/EN92011
3167Manual – Vision OS/2.x82412
2359LCD Monitor 9/PM82412
2302Inkjet B/682412
3110KB 101/FR72713
3140Screws <Z.16.S>72713
2350Desk – W/4872713
3112MB – S50063014
3170Smart Suite – V/SP63014
2339Paper – Std Printer63014
3134Screws <B.32.S>63014
2323Screws <B.32.P>63014
2319Screws <Z.24.S>63014
1910FG Stock – H53615
2322Screws <Z.28.P>53615
3124PS 110V /T53615
2976Drive Mount – D53615
3176Smart Suite – V/EN53615
2522Battery – EL44116
2496WSP DA-13044116
2430Compact 400/LQ44116
2211Wrist Pad44116
2264CDW 20/48/I44116
3216Manual – Vision Net6.344116
2252Monitor 21/HR/M44116
2457Cable PR/S/644116
2986Manual – Vision OS/2x +44116
2268Modem – 56/H/E44116
2335Mobile phone44116
1797Inkjet C/8/HQ35217
2245Monitor 19/SD/M35217
3193Plastic Stock – W/HD35217
2337Business Cards – 1000/2L35217
3224Card Organizer – 25035217
2439CPU D40035217
3097Cable Connector – 32R35217
2423C for SPNIX4.0 – 1 Seat35217
2422SPNIX4.0 – SAL35217
3082Modem – 56/90/E35217
2365Chemicals – TCS35217
2982Drive Mount – A35217
3220Manual – Vision OS/1.235217
2761Mouse +WP/CL35217
1820SPNIX3.3 – NL35217
2537Business Cards Box – 100035217
1948Envoy IC/5835217
2270Modem – 56/90/I35217
2721PC Bag – L/S35217
2536Business Cards – 250/2L35217
2999Laptop 16/8/11035217
3172Graphics – DIK+35217
3051Pens – 10/MP27418
2995SPNIX3.3 SAU27418
3350Plasma Monitor 10/LE/VGA27418
2409TD 7GB/827418
2394DIMM – 32MB27418
3099Cable Harness27418
3245Smart Suite – S4.0/FR27418
2471SPNIX3.3 SU27418
3173Graphics – SA27418
2464SPNIX4.0 – UL/A27418
2276SDRAM – 48 MB27418
3000Laptop 32/10/5627418
2340Chemicals – SW27418
3003Laptop 128/12/56/v90/11027418
2751MB – S45027418
2492SPNIX3.3 AU27418
2418Battery Backup (DA-130)27418
2462SPNIX4.0 – UL/N27418
3182Word Processing – SWP/V 4.527418
2243Monitor 17/HR/F27418
2274RAM – 32 MB27418
3187Plastic Stock – B/HD27418
2370PS 220V /HS/FR27418
3246Smart Suite – S4.0/SP27418
3501C for SPNIX4.0 – Sys27418
1822SPNIX4.0 – SL27418
3171Smart Suite – S3.3/EN27418
2272RAM – 16 MB27418
2459LaserPro 1200/8/BW27418
3290SPNIX3.3 DU27418
2870Pencil – Mech27418
2278Battery – NiHM27418
2257HD 8GB /I27418
3234Monitor Hinge – STD27418
2373Cable RS232 10/AF27418
3359SDRAM – 16 MB27418
1808SPNIX3.3 – UL/D27418
2467SPNIX4.0 – UL/D27418
3208Pencils – Wood27418
3086VRAM – 16 MB27418
2414HD 9.1GB @10000 /I111419
1791Industrial 700/HD111419
3251Project Management – V111419
2381CD-ROM 8x111419
3253Smart Suite – S4.0/EN111419
3252Project Management – S3.3111419
2400DIMM – 512 MB111419
1912SS Stock – 3mm111419
239532MB Cache /M111419
3060Monitor 17/HR111419
3353HD 10GB /R111419
3362Web Browser – SB/S 4.0111419
3204Envoy DS111419
3091VRAM – 64 MB111419
1825X25 – 1 Line License111419
3069HD 10GB /S111419
3090RAM – 48 MB111419
2470SPNIX4.0 – NL111419
2375GP 1024×768111419
2419Battery Backup (DA-290)111419
2424CDW 12/24111419
2266DVD 12x111419
24128MB EDO Memory111419
3209Sharpener – Pencil111419
3248Smart Suite – S4.0/DE111419
2402CD-ROM 600/E/24x111419
3197Spreadsheet – SSS/V 2.1111419
2752MB – S550111419
2410HD 8.4GB @5400111419
3077DVD 8x111419
3260Word Processing – SWP/S 4.4111419
2449OSI 1-4/IL111419
2403CD-ROM 600/I/24x111419
3256Spreadsheet – SSS/V 2.0111419
2415HD 9.1GB @7200111419
3183Word Processing – SWS/V 4.5111419
3101IC Browser – V111419
2058Mouse +WP111419
240664MB Cache /M111419
3250Graphics – DIK111419
2810Inkvisible Pens111419
1806SPNIX3.3 – UL/C111419
3515Lead Replacement111419
2254HD 10GB /I111419
2638Envoy DS/E111419
2093Pens – 10/FP111419
2377PS 110V HS/US111419
2782PC Bag – C/S111419
2262ZIP 100111419
2594FG Stock – L111419
1781CDW 20/48/E111419
3354HD 12GB /I111419
1803SPNIX3.3 – DL111419
2380Cable PR/15/P111419
2725Machine Oil111419
2878Router – ASR/2W111419
3511Paper – HQ Printer111419
2417Client ISO CP – V111419
1799SPNIX3.3 – SL111419
2382HD 18.2GB@10000 /I111419
3064Monitor 21/SD111419
2255HD 12GB @7200 /SE111419
2783Clips – Paper111419
2808Paper Tablet LY 8 1/2 x 11111419
1787CPU D300111419
2378DIMM – 128 MB111419
3191Plastic Stock – O111419
1782Compact 400/DQ111419
3087DIMM – 16 MB111419
2253HD 10GB @5400 /SE111419
2236Plasma Monitor 10/TFT/XGA111419
3258Web Browser – SB/V 1.0111419
SELECT
	oe.product_information.product_id,
    oe.product_information.product_name,
    COUNT(DISTINCT oe.order_items.order_id) AS distinct_purchases,
    RANK() OVER (
        ORDER BY COUNT(DISTINCT oe.order_items.order_id) DESC
    ) AS rank,
    DENSE_RANK() OVER (
        ORDER BY COUNT(DISTINCT oe.order_items.order_id) DESC
    ) AS dense_rank
FROM
    oe.order_items
    INNER JOIN
	oe.product_information
    	ON oe.order_items.product_id = oe.product_information.product_id
GROUP BY
    oe.product_information.product_id,
    oe.product_information.product_name
ORDER BY
    distinct_purchases DESC;

If desired, each ranking function’s rules could be expanded to account for those instances where ties occur. For example, in the instances where multiple products have the same distinct purchases count, the total sales generated by each of the products could be used to resolve the ties. Given the data type of total sales, this will largely result in the functions assigning the same integer value to each row. In fact, there is only one tie, and it is inconsequential to our scenario here. See the result set and corresponding SQL code below.

product_idproduct_namedistinct_purchasestotal_salesrankdense_rank
3106KB 101/EN218249011
3143Screws <B.28.S>181577722
3127LaserPro 600/6/BW1736435133
3123PS 220V /D1659428.544
3155Monitor Hinge – HD164505455
3150Card Holder – 25161517166
2289KB 101/ES157809977
3117Mouse C/E154248788
2311PS 220V /L1489411.799
3163Manual – Vision Net6.3/US14279921010
3133Video Card /3213251561111
2299PS 12V /P12419231212
3114MB – S900/650+1133978.41313
3165Manual – Vision Tools2.011254661414
3139Screws <S.16.S>11111161515
2326Plastic Stock – Y111036.21616
2308Video Card /E3210372771717
2293MB – S60010228961818
2316Screws <S.32.S>10130051919
3108KB E/EN9428652020
3129Sound Card STD9234422121
2334Resin91752.32222
2330Plastic Stock – R9698.52323
2359LCD Monitor 9/PM8180872.82424
2302Inkjet B/6848189.42525
3167Manual – Vision OS/2.x8246562626
2350Desk – W/487922708.62727
3110KB 101/FR7123832828
3140Screws <Z.16.S>770152929
3170Smart Suite – V/SP631363.23030
3112MB – S5006274713131
2339Paper – Std Printer6124753232
2319Screws <Z.24.S>688313333
3134Screws <B.32.S>661723434
2323Screws <B.32.P>657443535
3176Smart Suite – V/EN535513.43636
3124PS 110V /T5133573737
2322Screws <Z.28.P>569073838
2976Drive Mount – D528063939
1910FG Stock – H54614040
2252Monitor 21/HR/M41340794141
2496WSP DA-130423887.64242
2335Mobile phone4222734343
2264CDW 20/48/I4219014444
2430Compact 400/LQ416249.24545
2268Modem – 56/H/E4159774646
2986Manual – Vision OS/2x +427824747
2522Battery – EL413864848
2211Wrist Pad41263.94949
3216Manual – Vision Net6.349495050
2457Cable PR/S/644845151
2245Monitor 19/SD/M3619085252
2999Laptop 16/8/1103378405353
1948Envoy IC/58327306.45454
2365Chemicals – TCS3204385555
2337Business Cards – 1000/2L315424.25656
2422SPNIX4.0 – SAL3118165757
2439CPU D400398235858
2537Business Cards Box – 100039486.45959
1797Inkjet C/8/HQ39088.86060
3172Graphics – DIK+365046161
2536Business Cards – 250/2L353706262
2270Modem – 56/90/I337946363
3082Modem – 56/90/E320676464
2423C for SPNIX4.0 – 1 Seat320016565
1820SPNIX3.3 – NL318146666
2721PC Bag – L/S313606767
3220Manual – Vision OS/1.2312556868
2761Mouse +WP/CL310666969
3224Card Organizer – 25038007070
2982Drive Mount – A33277171
3193Plastic Stock – W/HD381.47272
3097Cable Connector – 32R348.47373
3003Laptop 128/12/56/v90/110297464.47474
1822SPNIX4.0 – SL251598.87575
2257HD 8GB /I245731.47676
2459LaserPro 1200/8/BW2406127777
3000Laptop 32/10/56232383.27878
3501C for SPNIX4.0 – Sys222668.87979
3171Smart Suite – S3.3/EN2203288080
2243Monitor 17/HR/F215613.48181
3182Word Processing – SWP/V 4.52119428282
3350Plasma Monitor 10/LE/VGA2117818383
2409TD 7GB/8211487.38484
2276SDRAM – 48 MB299338585
3246Smart Suite – S4.0/SP26793.68686
3245Smart Suite – S4.0/FR26220.58787
2462SPNIX4.0 – UL/N261698888
2274RAM – 32 MB259918989
2394DIMM – 32MB25480.29090
2467SPNIX4.0 – UL/D251799191
2340Chemicals – SW248829292
3173Graphics – SA242489393
2370PS 220V /HS/FR240679494
2418Battery Backup (DA-130)239009595
2471SPNIX3.3 SU23863.29696
2272RAM – 16 MB238079797
3290SPNIX3.3 DU236579898
3086VRAM – 16 MB231599999
3359SDRAM – 16 MB22442100100
2464SPNIX4.0 – UL/A21740101101
1808SPNIX3.3 – UL/D21595102102
2278Battery – NiHM21397103103
3234Monitor Hinge – STD21041104104
2995SPNIX3.3 SAU2751105105
2751MB – S4502493106106
3051Pens – 10/MP2372107107
2492SPNIX3.3 AU2293108108
2373Cable RS232 10/AF2144109109
3187Plastic Stock – B/HD2140.8110110
3099Cable Harness285.8111111
2870Pencil – Mech283.6112112
3208Pencils – Wood217.6113113
2236Plasma Monitor 10/TFT/XGA179741.2114114
2254HD 10GB /I137545.2115115
2255HD 12GB @7200 /SE123487.2116116
2253HD 10GB @5400 /SE111334.4117117
1799SPNIX3.3 – SL19614118118
2378DIMM – 128 MB18966.1119119
2415HD 9.1GB @720018157.6120120
2382HD 18.2GB@10000 /I18041121121
2410HD 8.4GB @540017368.9122122
2266DVD 12x16831123123
2400DIMM – 512 MB16688124124
3248Smart Suite – S4.0/DE15519.8125125
3091VRAM – 64 MB15282126126
3064Monitor 21/SD15085127127
3354HD 12GB /I14869128128
3253Smart Suite – S4.0/EN14756.4129129
3204Envoy DS14182130130
240664MB Cache /M13916131131
2402CD-ROM 600/E/24x13302132132
2424CDW 12/2413267133133
3069HD 10GB /S13080134134
2414HD 9.1GB @10000 /I13072.3135135
3183Word Processing – SWS/V 4.512961136136
2262ZIP 10012755137137
2375GP 1024×76812336138138
3353HD 10GB /R12271.5139139
2403CD-ROM 600/I/24x12266140140
3090RAM – 48 MB12244141141
3077DVD 8x12085.6142142
1781CDW 20/48/E12039.4143143
2782PC Bag – C/S11922144144
2419Battery Backup (DA-290)11656145145
2381CD-ROM 8x11649146146
3258Web Browser – SB/V 1.011638147147
2377PS 110V HS/US11632148148
2752MB – S55011548149149
3087DIMM – 16 MB11524.6150150
239532MB Cache /M11440151151
2638Envoy DS/E11233152152
3260Word Processing – SWP/S 4.411200153153
2449OSI 1-4/IL11170154154
3362Web Browser – SB/S 4.01940155155
1791Industrial 700/HD1788.7156156
3252Project Management – S3.31725157157
1803SPNIX3.3 – DL1715158158
2058Mouse +WP1667159159
3256Spreadsheet – SSS/V 2.01648160160
3060Monitor 17/HR1590161161
3101IC Browser – V1584162162
1787CPU D3001505163163
1782Compact 400/DQ1500164164
3250Graphics – DIK1486165165
2470SPNIX4.0 – NL1456166166
3251Project Management – V1416167167
2878Router – ASR/2W1340168168
2093Pens – 10/FP1323.4169169
2417Client ISO CP – V1297170170
2594FG Stock – L1243171171
3197Spreadsheet – SSS/V 2.11220172172
24128MB EDO Memory1190173173
1806SPNIX3.3 – UL/C1180174174
2783Clips – Paper1100175175
2380Cable PR/15/P193.5176176
2810Inkvisible Pens148177177
1912SS Stock – 3mm128178178
3209Sharpener – Pencil126179179
1825X25 – 1 Line License124180180
3511Paper – HQ Printer118181181
2725Machine Oil113.2182182
3515Lead Replacement14.4183183
3191Plastic Stock – O14.4183183
2808Paper Tablet LY 8 1/2 x 1110185184
SELECT
	oe.product_information.product_id,
    oe.product_information.product_name,
    COUNT(DISTINCT oe.order_items.order_id) AS distinct_purchases,
    SUM(oe.order_items.unit_price * oe.order_items.quantity) AS total_sales,
    RANK() OVER (
        ORDER BY
    		COUNT(DISTINCT oe.order_items.order_id) DESC,
    		SUM(oe.order_items.unit_price * oe.order_items.quantity) DESC
    ) AS rank,
    DENSE_RANK() OVER (
        ORDER BY
    		COUNT(DISTINCT oe.order_items.order_id) DESC,
    		SUM(oe.order_items.unit_price * oe.order_items.quantity) DESC
    ) AS dense_rank
FROM
    oe.order_items
    INNER JOIN
	oe.product_information
    	ON oe.order_items.product_id = oe.product_information.product_id
GROUP BY
    oe.product_information.product_id,
    oe.product_information.product_name
ORDER BY
    distinct_purchases DESC, total_sales DESC;

Provide the Context
Regardless of which ranking function you use, it is critical your audience understands the ranking system’s specification (i.e., how it works). The audience should be able to quickly discern the significance or insignificance of a particular row’s value. Additionally, messages surrounding ranking outcomes should contain supporting information, if necessary. For example, it would be misleading to state a sales representative’s performance, based on total sales, is in the top 10 when there are only 10 sales representatives or there are 10 other sales representatives with the same total sales value. Be transparent.

Wrap Up
In summary, ranking functions provide us a powerful way to quickly convey relative size, importance, and position within the context of our data. ROW_NUMBER is useful for assigning values to each row based on their position within the data while RANK and DENSE_RANK allow us to implement ranking systems based on specific instructions. When using ranking functions, it is important to provide all the necessary context and information to data consumers.

Knowledge Check
If you’d like to confirm your understanding on the use of ranking functions and other fundamental concepts, consider solving a handful of my practice problems here.