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

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

פונקציית חלון היא פונקציה הפועלת על "קבוצת שורות" (החלון_) אבל - בניגוד ל-GROUP BY - לא מפחית את מספר שורות: ערך המחושב מעל החלון מצורף לכל שורה של ה- תוצאה סופית.

זה הכלי הנכון לדירוג, מספור מתקדם, אחוזים על סך קבוצה, ופעולות רבות אחרות שהן מביכות או בלתי אפשרי עם GROUP BY.

התחביר: function() OVER (…)

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

רכיבים:

  • PARTITION BY - מגדיר את ה"קבוצות" (כמו GROUP BY, אבל את השורות להישאר נפרדים);
  • ORDER BY בתוך OVER(…) - מגדיר את הסדר בתוך מחיצה.

OVER () (סוגריים ריקים) פירושו "כל הטבלה כחלון בודד". שימושי לחישובים כמו "אחוז מסך הכל".

דירוג פונקציות

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)

הבדלים (עם ערכים 100, 100, 90, 80):

פונקציהעמדות
ROW_NUMBER1, 2, 3, 4 (תמיד ייחודי)
RANK1, 1, 3, 4 (קשרים חולקים עמדה, משאיר "פערים")
DENSE_RANK1, 1, 2, 3 (קשרים חולקים עמדה, ללא פערים)

דוגמה: דירוג מוצר לפי קטגוריה

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;

עבור כל category_id ה-RANK מתחיל מחדש מ-1 ומסדר בירידה מחיר: אתה מקבל את דירוג המוצרים בתוך כל קטגוריה, באחת ירייה.

מספור פרוגרסיבי

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;

בהזמנה הראשונה של כל לקוח יהיו row_num = 1, השנייה 2 וכו'.

נסה את זה

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

עבור כל מוצר הצג שם, category_id, מחיר ודירוג (הדירוג לפי מחיר יורד בתוך הקטגוריה; השתמש ב-RANK). סדר לפי עולה של category_id ודירוג עולה.

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

PARTITION BY category_id groups, ORDER BY price DESC הזמנות בתוך הקבוצה.

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

סקירת התרגיל

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

עבור כל הזמנה הצג מזהה, customer_id, ordered_at ו-row_num (פרוגרסיבי ROW_NUMBER ללקוח, מסודר לפי עולה ordered_at). הזמנה לפי זיהוי_לקוח ו-row_num.

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

ROW_NUMBER הוא תמיד ייחודי בתוך המחיצה.

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