ROW_NUMBER
Feb 23, 2026
·
5
min read
Category: Window/Analytic Functions
Platform Support:
✅ Snowflake | ✅ BigQuery | ✅ Databricks
Description
ROW_NUMBER assigns a unique sequential integer to rows within a partition of a result set, starting at 1 for the first row in each partition. Unlike RANK and DENSE_RANK, ROW_NUMBER always produces unique values even when there are ties.
Syntax
Platform-Specific Notes
Snowflake:
Fully supported
Can be used with QUALIFY clause for filtering
Deterministic ordering requires unique ORDER BY values
BigQuery:
Fully supported
Can be used with QUALIFY clause
Works efficiently with partitioned tables
Databricks:
Fully supported
Standard Spark SQL implementation
Cannot use QUALIFY (must use subquery)
Example 1: Ranking Sales by Amount
All Platforms:
Sample Data (sales table):
employee_name | sale_amount | sale_date |
|---|---|---|
Alice | 5000 | 2024-01-15 |
Bob | 3500 | 2024-01-16 |
Charlie | 4200 | 2024-01-17 |
Diana | 3500 | 2024-01-18 |
Eric | 6100 | 2024-01-19 |
Result:
employee_name | sale_amount | sale_date | overall_rank |
|---|---|---|---|
Eric | 6100 | 2024-01-19 | 1 |
Alice | 5000 | 2024-01-15 | 2 |
Charlie | 4200 | 2024-01-17 | 3 |
Bob | 3500 | 2024-01-16 | 4 |
Diana | 3500 | 2024-01-18 | 5 |
Note: Bob and Diana have the same sale_amount but get different row numbers (4 and 5) based on the secondary ordering.
Example 2: Row Number Within Partitions
All Platforms:
Sample Data (employees table):
department | employee_name | salary | hire_date |
|---|---|---|---|
Sales | Alice | 75000 | 2022-03-15 |
Sales | Bob | 65000 | 2021-06-10 |
Sales | Carol | 75000 | 2023-01-20 |
IT | Diana | 90000 | 2020-08-05 |
IT | Eric | 85000 | 2021-11-12 |
IT | Frank | 80000 | 2022-02-28 |
Marketing | Grace | 72000 | 2021-09-15 |
Result:
department | employee_name | salary | hire_date | dept_rank |
|---|---|---|---|---|
IT | Diana | 90000 | 2020-08-05 | 1 |
IT | Eric | 85000 | 2021-11-12 | 2 |
IT | Frank | 80000 | 2022-02-28 | 3 |
Marketing | Grace | 72000 | 2021-09-15 | 1 |
Sales | Alice | 75000 | 2022-03-15 | 1 |
Sales | Carol | 75000 | 2023-01-20 | 2 |
Sales | Bob | 65000 | 2021-06-10 | 3 |
Example 3: Deduplication with QUALIFY (Snowflake/BigQuery)
Snowflake/BigQuery:
Databricks Alternative:
Sample Data (customer_updates table):
customer_id | updated_at | |
|---|---|---|
101 | 2024-01-10 | |
101 | 2024-02-15 | |
102 | 2024-01-05 | |
103 | 2024-01-20 | |
103 | 2024-02-01 | |
103 | 2024-03-10 |
Result:
customer_id | updated_at | |
|---|---|---|
101 | 2024-02-15 | |
102 | 2024-01-05 | |
103 | 2024-03-10 |
ROW_NUMBER vs RANK vs DENSE_RANK
Function | Behavior with Ties | Example (values: 100, 95, 95, 90) |
|---|---|---|
ROW_NUMBER | Assigns unique numbers arbitrarily | 1, 2, 3, 4 |
RANK | Skips numbers after ties | 1, 2, 2, 4 |
DENSE_RANK | No gaps in numbering | 1, 2, 2, 3 |
Common Use Cases
Deduplication: Remove duplicate records, keeping the most recent
Pagination: Implement efficient page-based data retrieval
Top N per group: Get top performers in each department/category
Sequential numbering: Generate invoice numbers, ticket IDs
Time-series analysis: Number events in chronological order
Performance Tips
Use specific ORDER BY columns for deterministic results
Combine with PARTITION BY to limit the scope of numbering
In Snowflake/BigQuery, use QUALIFY instead of subqueries for better performance
Index columns used in PARTITION BY and ORDER BY for better performance





