CodeGym /Courses /SQL SELF /Syntax of OVER() and Its Key Features

Syntax of OVER() and Its Key Features

SQL SELF
Level 29 , Lesson 2
Available

OVER() is an instruction that tells SQL which set of rows to apply a window function to. You can think of it as a way to define the "window" of data for a window function. Imagine you have a room full of people, and you want to count how many people are standing on each square meter of the floor. OVER() tells you exactly which part of the room you should focus on. In other words, it defines which set of rows the function will work on.

The OVER() operator is used exclusively with window functions to perform operations on rows from one or more tables, without grouping the data.

Syntax:

window_function() OVER (
    [PARTITION BY ...]
    [ORDER BY ...]
    [ROWS/RANGE ...]
)

Where:

  • PARTITION BY — splits the dataset into logical groups
  • ORDER BY — sets the order of rows within each group
  • ROWS/RANGE — specifies the size of the "window" (for example, current row + 1 next row)

Example: OVER() Without Parameters

When OVER() is used without any extra parameters, it means the function before it will work over the entire dataset.

SELECT
    employee_id,
    salary,
    ROW_NUMBER() OVER () AS row_num -- ROW_NUMBER() will be applied to all result rows
FROM employees;

What's happening?

  1. ROW_NUMBER() assigns a unique number to each row.
  2. Since there are no parameters in OVER(), all rows from the employees table are treated as a single group.

Result:

employee_id salary row_num
1 50000 1
2 60000 2
3 55000 3

Using PARTITION BY to Set Groups

Alright, now imagine you want to number employees not across the whole company, but within each department. That's where PARTITION BY comes in.

PARTITION BY inside OVER() splits the data into groups (or "partitions"). For each group, the function calculates its value separately. So, if ROW_NUMBER() was a waiter, it would start numbering from 1 at each "table" (partition).

Example: using PARTITION BY

SELECT
    department_id,
    employee_id,
    salary,
    ROW_NUMBER() OVER (PARTITION BY department_id) AS row_num
FROM employees;

What's happening?

  1. Data from the employees table is split into groups by department_id.
  2. Within each group, rows are assigned a sequential number using ROW_NUMBER().

Result:

department_id employee_id salary row_num
1 1 50000 1
1 3 55000 2
2 2 60000 1

Using ORDER BY to Set Order

Now let's add a bit of structure. Imagine you want to number the rows, but in a specific order, like starting from the highest salary. This is where ORDER BY comes in.

ORDER BY defines the order in which rows will be processed by the window function.

Example: using ORDER BY inside OVER()

SELECT
    department_id,
    employee_id,
    salary,
    RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank
FROM employees;

What's happening?

  1. Data is split into groups (PARTITION BY department_id).
  2. Within each group, rows are sorted by salary descending (ORDER BY salary DESC).
  3. Each row gets a rank based on the sorting.

Result:

department_id employee_id salary rank
1 3 55000 1
1 1 50000 2
2 2 60000 1

Combining Window Functions

SQL lets you use multiple window functions in one query, and each one can work with its own unique set of rules. It's like having music playing and people counting in the same room at the same time — each process is independent!

Example: multiple window functions

SELECT
    department_id,
    employee_id,
    salary,
    ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num,
    AVG(salary) OVER (PARTITION BY department_id) AS avg_salary
FROM employees;

What's happening?

  1. ROW_NUMBER() numbers the rows in each group by descending salary.
  2. AVG() calculates the average salary in each group.

Result:

department_id employee_id salary row_num avg_salary
1 3 55000 1 52500
1 1 50000 2 52500
2 2 60000 1 60000

Real-Life Examples

Window functions with OVER() are used in tons of real-world scenarios. Here are just a few examples:

  • Sales analytics: ranking products by sales count in each category.
  • Rankings: figuring out student positions in each group by average grade.
  • Time series: cumulative sales sum over time.

Example from sales analytics:

SELECT
    category_id,
    product_id,
    product_name,
    SUM(sales) OVER (PARTITION BY category_id ORDER BY sales DESC) AS cumulative_sales
FROM products;

Common Mistakes When Working with Window Functions

  1. Missing PARTITION BY

If you don't use PARTITION BY, the window function is applied to the whole table. This can lead to unexpected results, especially if you expected grouping.

💡 Make sure you explicitly specify how the table should be split — for example, by user, order, or category.


  1. Incorrect data types in ORDER BY

ORDER BY inside a window function is sensitive to data types. If you sort by a date field stored as text (VARCHAR), the order might be alphabetical, not chronological.

💡 Convert such fields to the right type (DATE, INTEGER, etc.) before sorting.

  1. Sloppy handling of the window frame

If OVER() contains an ORDER BY but you don’t specify a frame, PostgreSQL uses RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW by default. In RANGE mode, all rows with the same value of the sort key fall into the same frame group, so a running total can "jump" over duplicates. If you want a strict row-by-row running total, specify ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW explicitly.

💡 For precise control, use ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW if you want a running total from the start up to the current row.

  1. Incorrect handling of NULL

Window functions can handle NULL values differently. For example, RANK() and DENSE_RANK() will treat NULL as a value and assign it its own rank.

💡 Use NULLS LAST or NULLS FIRST in ORDER BY if it matters where NULL values should go.

  1. Using aggregate window functions instead of regular ones

Sometimes people use aggregate window functions (SUM() OVER(...)) where regular aggregates with GROUP BY would be enough, which makes the query more complex and slower.

💡 Only use window functions when you need to keep row-level detail.

2
Task
SQL SELF, level 29, lesson 2
Locked
Row Numbering in a Table
Row Numbering in a Table
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION