דילוג לתוכן המרכזי
eLearner.app
מודול 7 · שיעור 2 מתוך 426/57 בקורס~14 min
שיעורי מודול (2/4)

פונקציות חלון: דירוגים וחישובים לקבוצה

A window function is a function that operates on a "group of rows" (the window) but — unlike GROUP BYdoes not reduce the number of rows: a value computed over the window is attached to each row of the final result.

It's the right tool for rankings, progressive numbering, percentages over a group total, and many other operations that are awkward or impossible with GROUP BY.

The syntax: function() OVER (…)

SQL
ROW_NUMBER() OVER (PARTITION BY colonna ORDER BY colonna2)

Components:

  • PARTITION BY — defines the "groups" (like GROUP BY, but the rows stay separate);
  • ORDER BY inside OVER(…) — defines the order within the partition.

OVER () (empty parentheses) means "the whole table as a single window". Useful for computations like "percentage of total".

Ranking functions

SQL
ROW_NUMBER() OVER (PARTITION BY p ORDER BY o)
RANK()       OVER (PARTITION BY p ORDER BY o)
DENSE_RANK() OVER (PARTITION BY p ORDER BY o)

Differences (with values 100, 100, 90, 80):

FunctionPositions
ROW_NUMBER1, 2, 3, 4 (always unique)
RANK1, 1, 3, 4 (ties share a position, leaves "gaps")
DENSE_RANK1, 1, 2, 3 (ties share a position, without gaps)

Example: product ranking per category

SQL
SELECT name,
       category_id,
       price,
       RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS rank
FROM   products
ORDER BY category_id, rank;

For each category_id the RANK restarts from 1 and orders by descending price: you get the ranking of products within each category, in one shot.

Progressive numbering

SQL
-- Progressive order number for each customer:
SELECT id,
       customer_id,
       ordered_at,
       ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY ordered_at) AS row_num
FROM   orders
ORDER BY customer_id, row_num;

Each customer's first order will have row_num = 1, the second 2, etc.

Try it

פעילות גופנית#sql.m7.l2.e1
ניסיונות: 0טוען...

For each product show name, category_id, price and rank (the ranking by descending price WITHIN the category; use RANK). Order by ascending category_id and ascending rank.

טוען עורך...
הצג רמז

PARTITION BY category_id groups, ORDER BY price DESC orders within the group.

הפתרון זמין לאחר 3 ניסיונות

Review exercise

פעילות גופנית#sql.m7.l2.e2
ניסיונות: 0טוען...

For each order show id, customer_id, ordered_at and row_num (progressive ROW_NUMBER per customer, ordered by ascending ordered_at). Order by customer_id and row_num.

טוען עורך...
הצג רמז

ROW_NUMBER is always unique within the partition.

הפתרון זמין לאחר 3 ניסיונות