ROW_NUMBER function in SQL - Time & Space Complexity
We want to understand how the time to run a query using the ROW_NUMBER function changes as the data grows.
Specifically, how does numbering rows in order affect performance when the table gets bigger?
Analyze the time complexity of the following code snippet.
SELECT
employee_id,
department_id,
salary,
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank
FROM employees;
This query assigns a rank number to each employee within their department based on salary, ordering from highest to lowest.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Sorting each department's employees by salary.
- How many times: Once per department, sorting all employees in that department.
As the number of employees grows, the database must sort more rows within each department.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 log 10 operations for sorting |
| 100 | About 100 log 100 operations for sorting |
| 1000 | About 1000 log 1000 operations for sorting |
Pattern observation: The work grows a bit faster than the number of rows because sorting takes more effort as data grows.
Time Complexity: O(n log n)
This means the time to assign row numbers grows a little faster than the number of rows because sorting is involved.
[X] Wrong: "ROW_NUMBER just counts rows one by one, so it must be very fast and linear."
[OK] Correct: The function needs to sort rows within each group first, which takes more time than just counting.
Understanding how window functions like ROW_NUMBER scale helps you explain query performance clearly and shows you know what happens behind the scenes.
"What if we removed the PARTITION BY clause? How would the time complexity change?"
Practice
ROW_NUMBER() function do in SQL?Solution
Step 1: Understand the purpose of ROW_NUMBER()
TheROW_NUMBER()function assigns a unique sequential integer to rows in the result set, starting at 1.Step 2: Compare with other options
Counting rows, summing values, or filtering rows are done by other SQL functions likeCOUNT(),SUM(), orWHEREclause, notROW_NUMBER().Final Answer:
Assigns a unique sequential number to each row in the result set. -> Option DQuick Check:
ROW_NUMBER() = unique row numbers [OK]
- Confusing ROW_NUMBER() with COUNT()
- Thinking ROW_NUMBER() filters rows
- Assuming ROW_NUMBER() sums values
salary in descending order?Solution
Step 1: Identify correct ROW_NUMBER() syntax
The correct syntax usesROW_NUMBER() OVER (ORDER BY column)to assign numbers ordered by a column.Step 2: Check each option
OnlySELECT ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn FROM employees;correctly usesOVER (ORDER BY salary DESC). The other options omit the OVER clause, pass arguments directly to ROW_NUMBER(), or misplace the ORDER BY clause.Final Answer:
SELECT ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn FROM employees; -> Option BQuick Check:
ROW_NUMBER() needs OVER with ORDER BY [OK]
- Omitting OVER() clause
- Placing ORDER BY outside OVER()
- Passing column directly to ROW_NUMBER()
sales with columns region and amount, what will this query return?SELECT region, amount, ROW_NUMBER() OVER (PARTITION BY region ORDER BY amount DESC) AS rn FROM sales;
Solution
Step 1: Understand PARTITION BY effect
UsingPARTITION BY regionrestarts the row numbering for each region group separately.Step 2: Understand ORDER BY inside ROW_NUMBER()
Ordering byamount DESCmeans the highest amount in each region gets row number 1, next highest 2, and so on.Final Answer:
A unique row number for each sale, restarting at 1 for each region, ordered by highest amount first. -> Option CQuick Check:
ROW_NUMBER() with PARTITION BY = numbering per group [OK]
- Ignoring PARTITION BY and numbering all rows globally
- Confusing ORDER BY direction
- Thinking ROW_NUMBER() counts rows
SELECT name, ROW_NUMBER() ORDER BY salary FROM employees;
Solution
Step 1: Check ROW_NUMBER() syntax
TheROW_NUMBER()function requires anOVER()clause specifying ordering or partitioning.Step 2: Analyze the query
The query usesROW_NUMBER()withoutOVER(), which causes a syntax error. ORDER BY inside SELECT is invalid without OVER().Final Answer:
Missing OVER() clause after ROW_NUMBER(). -> Option AQuick Check:
ROW_NUMBER() must have OVER() [OK]
- Forgetting OVER() after ROW_NUMBER()
- Placing ORDER BY outside OVER()
- Assuming ROW_NUMBER() works without ordering
employees table. Which query correctly uses ROW_NUMBER() to achieve this?Solution
Step 1: Use ROW_NUMBER() with PARTITION BY department
To get top 2 per department, assign row numbers restarting for each department ordered by salary descending.Step 2: Filter rows with row number less than or equal to 2
Wrap the query as a subquery and filter wherern <= 2to get top 2 employees per department.Final Answer:
SELECT * FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn FROM employees) sub WHERE rn <= 2; -> Option AQuick Check:
ROW_NUMBER() + PARTITION + filter = top N per group [OK]
- Not using PARTITION BY to group by department
- Filtering on rn in the same SELECT without subquery
- Using LIMIT without partitioning
Ready to prove it?
Pass the test and this pattern moves unknown
