1. Home
SQL

SQL Tutorial: Learn Structured Query Language Basics

Learn all SQL tutorial concepts in detail and master your career today.

  • 59
  • 9 Hours
right-top-arrow

Tutorial Playlist

81 Lessons
56

Understanding the ROW_NUMBER() Function in SQL

Updated on 19/07/2024443 Views

Introduction

When collaborating with huge datasets in SQL, it is usually necessary to assign serial numbers to each row based on specific standards. This is where the ROW_NUMBER() feature enters into play. In this post, we'll dive deep right into the ROW NUMBER function in SQL, exploring its phrase structure, use, and useful examples. Whether you are a novice or a seasoned SQL individual, recognizing exactly how to utilize the ROW_NUMBER() function efficiently can significantly enhance your information analysis and control capacities.

Overview

What is the ROW_NUMBER() Function? 

The ROW_NUMBER() function is a window function in SQL that assigns a unique, sequential number to each row within a partition of a result set. It is used to generate a unique identifier for each row based on the specified ordering criteria.

The ROW NUMBER function in SQL operates on a set of rows defined by the OVER clause, which determines the partitioning and ordering of the rows. It assigns a unique, incremental number to each row within each partition, starting from 1.

Here's a basic example to illustrate the concept:

SELECT 

    ROW_NUMBER() OVER (ORDER BY ColumnName) AS RowNum,

    ColumnName1,

    ColumnName2

FROM 

    TableName;

In this example, the ROW_NUMBER function in SQL is used to assign row numbers to records within each DepartmentID, ordered by Salary in descending order. This results in a new column, RowNum, which contains the assigned row numbers for each record, grouped by department.

Syntax and Usage

The general syntax of the ROW_NUMBER in SQL is as follows:

ROW_NUMBER() OVER (

    [PARTITION BY partition_expression]

    ORDER BY sort_expression [ASC | DESC]

)

  • partition_expression: Specifies the column(s) used to divide the result set into partitions. Each partition will have its own set of row numbers. This part is optional.
  • sort_expression: Specifies the column(s) used to determine the ordering of the rows within each partition. The row numbers are assigned based on this ordering.
  • ASC | DESC: Specifies the sort order, either ascending (default) or descending.

Sample Data

-- Create the database

CREATE DATABASE EmployeeDB;

GO

-- Use the EmployeeDB database

USE EmployeeDB;

GO

-- Create the Employees table

CREATE TABLE Employees (

    EmployeeID INT PRIMARY KEY,

    FirstName VARCHAR(50),

    LastName VARCHAR(50),

    DepartmentID INT,

    Salary DECIMAL(10, 2)

);

-- Insert dummy data into the Employees table

INSERT INTO Employees (EmployeeID, FirstName, LastName, DepartmentID, Salary)

VALUES

    (1, 'John', 'Doe', 1, 5000.00),

    (2, 'Jane', 'Smith', 1, 6000.00),

    (3, 'Michael', 'Johnson', 1, 5500.00),

    (4, 'Emily', 'Brown', 2, 4500.00),

    (5, 'David', 'Wilson', 2, 5200.00),

    (6, 'Sarah', 'Taylor', 2, 4800.00),

    (7, 'Robert', 'Anderson', 3, 6500.00),

    (8, 'Olivia', 'Thomas', 3, 7000.00),

    (9, 'James', 'Jackson', 3, 6800.00),

    (10, 'Emma', 'White', 1, 5800.00),

    (11, 'Daniel', 'Harris', 2, 5100.00),

    (12, 'Sophia', 'Martin', 3, 7200.00),

    (13, 'Matthew', 'Thompson', 1, 6200.00),

    (14, 'Ava', 'Garcia', 2, 4900.00),

    (15, 'Andrew', 'Martinez', 3, 7500.00);

Here is an example that demonstrates the use of ROW_NUMBER() with partitioning:

SELECT 

    ROW_NUMBER() OVER (PARTITION BY DepartmentID ORDER BY Salary DESC) AS RowNum,

    EmployeeID,

    DepartmentID,

    Salary

FROM 

    Employees;

In this example, the ROW NUMBER function in SQL assigns row numbers within each DepartmentID dividing, bought by Salary in descending order. The resulting RowNum column will certainly contain the appointed row numbers for every department.

What is the Need for a ROW_NUMBER() Function?

The ROW_NUMBER() feature offers several vital functions in SQL:

  • Unique Row Recognition: It offers a way to distinctively determine each row within a result set, even if the information itself does not have a natural distinct identifier.
  • Pagination: ROW_NUMBER() is usually used for carrying out pagination in SQL inquiries. By designating row numbers, you can quickly retrieve a specific part of the rows based on their position.
  • Position and Top-N Evaluation: When utilized in mix with partitioning and ordering, ROW_NUMBER() allows you to place rows within teams or dividers based upon details criteria. This works for scenarios like discovering the top N documents within each group.
  • To Eliminate Matches: By designating special row numbers, you can identify and remove replicate rows from a result set.
  • Complicated Filtering: ROW_NUMBER() in SQL makes it possible for complicated filtering system scenarios where you need to use problems based on the relative position of rows within dividers.

Here is an example that demonstrates the use of ROW_NUMBER() for pagination:

SELECT *

FROM (

    SELECT 

        ROW_NUMBER() OVER (ORDER BY EmployeeID) AS RowNum,

        EmployeeID,

        FirstName,

        LastName

    FROM 

        Employees

) AS EmployeeWithRowNumber

WHERE 

    RowNum BETWEEN 11 AND 20;

In this example, the ROW_NUMBER() function appoints row numbers based on the EmployeeID column. The outer inquiry then filters the rows where RowNum is between 11 and 20, effectively fetching the 2nd web page of outcomes (presuming 10 rows per web page).

Example Queries

These examples showcase different scenarios where the ROW_NUMBER() function can be applied:

Finding the top 3 employees with the highest salary in each department

SELECT *

FROM (

    SELECT 

        ROW_NUMBER() OVER (PARTITION BY DepartmentID ORDER BY Salary DESC) AS RowNum,

        EmployeeID,

        DepartmentID,

        Salary

    FROM 

        Employees

) AS EmployeeWithRowNumber

WHERE 

    RowNum <= 3;

Removing duplicates based on specific columns

WITH CTE AS (

    SELECT 

        ROW_NUMBER() OVER (PARTITION BY FirstName, LastName ORDER BY EmployeeID) AS RowNum,

        EmployeeID,

        FirstName,

        LastName,

        DepartmentID,

        Salary

    FROM 

        Employees

)

DELETE FROM Employees

WHERE EmployeeID IN (

    SELECT EmployeeID

    FROM CTE

    WHERE RowNum > 1

);

In this example, the common table expression (CTE) assigns row numbers within partitions defined by Column1 and Column2. The DELETE statement then removes rows where RowNum is greater than 1, effectively keeping only the first occurrence of each unique combination of Column1 and Column2.

Pagination - Retrieving the second page of results (assuming 5 rows per page)

SELECT *

FROM (

    SELECT 

        ROW_NUMBER() OVER (ORDER BY EmployeeID) AS RowNum,

        EmployeeID,

        FirstName,

        LastName,

        DepartmentID,

        Salary

    FROM 

        Employees

) AS EmployeeWithRowNumber

WHERE 

    RowNum BETWEEN 6 AND 10;

ROW_NUMBER() vs. Other Ranking Functions

Function

ROW_NUMBER()

RANK()

DENSE_RANK()

Description

Assigns a unique, sequential number to each row within a partition.

Assigns the same rank to ties and skips the next rank value.

Assigns the same rank to ties but does not skip the next rank value.

Handling Ties

Assigns a unique number to each row, even if there are ties in the ordering criteria.

Assigns the same rank to ties and skips the next rank value.

Assigns the same rank to ties but does not skip the next rank value.

Use Cases

  • Generating unique row identifiers
  • Pagination
  • Eliminating duplicates
  • Ranking with gaps
  • Leaderboards with ties
  • Percentile calculations
  • Ranking without gaps
  • Continuous ranking
  • Grouping based on ranks

Performance

  • Generally faster than RANK() and DENSE_RANK()
  • Requires less memory overhead
  • Slower than ROW_NUMBER() due to handling ties
  • Requires more memory for larger datasets
  • Slower than ROW_NUMBER() due to handling ties
  • Requires more memory for larger datasets

ROW_NUMBER()

Syntax

ROW_NUMBER() OVER (

    [PARTITION BY partition_expression]

    ORDER BY sort_expression [ASC | DESC]

)

  • partition_expression: Specifies the column(s) used to divide the result set into partitions. Each partition will have its own set of row numbers. This part is optional.
  • sort_expression: Specifies the column(s) used to determine the ordering of the rows within each partition. The row numbers are assigned based on this ordering.
  • ASC | DESC: Specifies the sort order, either ascending (default) or descending.

Example:

SELECT 

    ROW_NUMBER() OVER (PARTITION BY DepartmentID ORDER BY Salary DESC) AS RowNum,

    EmployeeID,

    DepartmentID,

    Salary

FROM 

    Employees;

RANK()

Syntax 

RANK() OVER (

    [PARTITION BY partition_expression]

    ORDER BY sort_expression [ASC | DESC]

)

  • partition_expression: Specifies the column(s) used to divide the result set into partitions. Each partition will have its own set of ranks. This part is optional.
  • sort_expression: Specifies the column(s) used to determine the ordering of the rows within each partition. The ranks are assigned based on this ordering.
  • ASC | DESC: Specifies the sort order, either ascending (default) or descending.

Example:

SELECT 

    RANK() OVER (PARTITION BY DepartmentID ORDER BY Salary DESC) AS RankNum,

    EmployeeID,

    DepartmentID,

    Salary

FROM 

    Employees;

DENSE_RANK()

Syntax

DENSE_RANK() OVER (

    [PARTITION BY partition_expression]

    ORDER BY sort_expression [ASC | DESC]

)

  • partition_expression: Specifies the column(s) used to divide the result set into partitions. Each partition will have its own set of dense ranks. This part is optional.
  • sort_expression: Specifies the column(s) used to determine the ordering of the rows within each partition. The dense ranks are assigned based on this ordering.
  • ASC | DESC: Specifies the sort order, either ascending (default) or descending.

Example:

SELECT 

    DENSE_RANK() OVER (PARTITION BY DepartmentID ORDER BY Salary DESC) AS DenseRankNum,

    EmployeeID,

    DepartmentID,

    Salary

FROM 

    Employees;

Wrapping Up!

The ROW_NUMBER() function is a powerful tool in SQL that allows you to assign unique, sequential numbers to rows within a result set. By leveraging the ROW_NUMBER() function, you can tackle a wide range of data analysis and manipulation tasks, such as pagination, ranking, duplicate elimination, and complex filtering.

Understanding the syntax and usage of ROW_NUMBER(), along with its ability to partition and order rows, empowers you to write more efficient and effective SQL queries. Whether you're working with small or large datasets, mastering the ROW_NUMBER() function is a valuable skill for any SQL practitioner. So, start exploring the capabilities of ROW_NUMBER() in your SQL queries and unlock new possibilities for data analysis and manipulation. 

If you're looking for a powerful tool to streamline your data analysis and visualization workflows, check out Tooljet. Tooljet offers a user-friendly interface and a wide range of features to help you create interactive dashboards, reports, and applications with ease.

Frequently Asked Questions (FAQs)

1. How do you count row numbers in SQL?

To count row numbers in SQL, you can make use of the ROW_NUMBER() feature. It appoints a special, sequential number per row within a result set based on the specified ordering requirements.

2. How to get a row ID in SQL?

In SQL, you can utilize the ROW_NUMBER() function to create a distinct row ID for each row in the result set. By specifying the proper requirements, you can designate a one-of-a-kind identifier per row.

3. What is the difference between RANK(), ROW_NUMBER(), and DENSE_RANK() in SQL?

ROW_NUMBER(): Assigns a unique, sequential number to each row within a partition, even if there are ties in the ordering criteria.

RANK(): Assigns the same rank to ties and skips the next rank value. For example, if two rows are tied for rank 2, the next row will be rank 4.

DENSE_RANK(): Assigns the same rank to ties but does not skip the next rank value. For example, if two rows are tied for rank 2, the next row will be rank 3.

4. How can ROW_NUMBER() OVER() be used?

ROW_NUMBER() OVER() is utilized to assign one-of-a-kind, consecutive numbers to rows within a result set. It is generally made use of in mix with the dividers BY and ORDER BY provisions to determine the dividing and purchasing of the rows.

5. How to write ROW_NUMBER() in SQL Server?

In SQL Server, you can use the ROW_NUMBER() function as follows:

SELECT 

    ROW_NUMBER() OVER (ORDER BY ColumnName) AS RowNum,

    ColumnName1,

    ColumnName2

FROM 

    TableName;

This will assign a unique, sequential number to each row based on the specified ordering criteria.

6. What is Rowid and Rownum in SQL?

Rowid: In some data sources like Oracle, Rowid is a special identifier for every row in a table. It is a pseudo-column that represents the physical address of a row.

Rownum: Rownum is a pseudo-column in Oracle that appoints a distinct, sequential number to every row returned by an inquiry. It resembles the ROW_NUMBER() feature yet has some constraints.

7. How to delete duplicate rows using ROW_NUMBER()?

To delete duplicate rows using ROW_NUMBER(), you can use a common table expression (CTE) and a DELETE statement. Here's an example:

WITH CTE AS (

    SELECT 

        ROW_NUMBER() OVER (PARTITION BY Column1, Column2 ORDER BY Column1) AS RowNum,

        Column1,

        Column2,

        Column3

    FROM 

        TableName

)

DELETE FROM CTE

WHERE RowNum > 1;

This query appoints row numbers within partitions defined by Column1 and Column2 and further deletes rows where RowNum is above 1, properly maintaining only the first occurrence of each distinct combination.

8. Can we use Rownum in the WHERE clause?

In Oracle, you cannot directly use Rownum in the WHERE clause to filter rows based on their position. However, you can use a subquery or a derived table to achieve the desired result. Here's an example:

SELECT *

FROM (

    SELECT 

        Rownum AS RNum,

        ColumnName1,

        ColumnName2

    FROM 

        TableName

)

WHERE RNum BETWEEN 1 AND 10;

This query first appoints row numbers utilizing Rownum in a subquery and then filterings system the rows based upon the appointed row numbers.

9. What is the alternative to Rownum in SQL?

The alternative to Rownum in SQL is the ROW_NUMBER() feature. ROW_NUMBER() is a common SQL feature that provides similar capability to Rownum yet with even more adaptability and compatibility across different data source systems.

10. Does SQL Server have Rownum?

SQL Server does not have a straight equivalent to Oracle's Rownum pseudo-column. Nevertheless, you can attain comparable functionality utilizing the ROW_NUMBER() feature in SQL Server.

SELECT 

    ROW_NUMBER() OVER (ORDER BY ColumnName) AS RowNum,

    ColumnName1,

    ColumnName2

FROM 

    TableName;

This query assigns unique, sequential row numbers to each row based on the specified ordering criteria, similar to Rownum in Oracle.

Mukesh Kumar

Mukesh Kumar

Working with upGrad as a Senior Engineering Manager with more than 10+ years of experience in Software Development and Product Management.

Get Free Career Counselling
form image
+91
*
By clicking, I accept theT&Cand
Privacy Policy
image
Join 10M+ Learners & Transform Your Career
Learn on a personalised AI-powered platform that offers best-in-class content, live sessions & mentorship from leading industry experts.
right-top-arrowleft-top-arrow

upGrad Learner Support

Talk to our experts. We’re available 24/7.

text

Indian Nationals

1800 210 2020

text

Foreign Nationals

+918045604032

Disclaimer

upGrad does not grant credit; credits are granted, accepted or transferred at the sole discretion of the relevant educational institution offering the diploma or degree. We advise you to enquire further regarding the suitability of this program for your academic, professional requirements and job prospects before enr...