דילוג לתוכן המרכזי
מודול 3 · שיעור 3 מתוך 411/57 בקורס~10 min
שיעורי מודול (3/4)

קיבוץ עם GROUP BY

במודול 2 למדת שCOUNT(*), AVG(...), SUM(...) מפחיתים את כל שורות לשורת תוצאה יחידה. אבל מה אם אתה רוצה משכורת ממוצעת לכל מחלקה, לא לכל החברה? אתה רוצה שורה אחת לכל קבוצה. זה התפקיד של GROUP BY.

התחביר

SQL
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM   table
GROUP BY grouping_column;

קרא באנגלית: "חלק את השורות לקבוצות שחולקות את אותו ערך של grouping_column, ולכל קבוצה מחשב את המצטבר".

SQL
-- Average salary per department:
SELECT department_id, AVG(salary) AS average
FROM   employees
GROUP BY department_id;

לתוצאה יש שורה אחת עבור כל department_id נפרד שנמצא ב- employees. תקבלו 5 שורות: אחת לכל אחת מארבע המחלקות (1, 2, 3, 4) ועוד אחד עבור NULL (אנדריאה קוסטה).

עם JOIN לשמות קריאים

לעתים קרובות אתה רוצה לקבץ לפי department_id אבל להציג את שם של מחלקה. אתה משלב את GROUP BY עם JOIN:

SQL
SELECT d.name AS department,
       COUNT(*)    AS count,
       AVG(e.salary) AS average_salary
FROM   employees   AS e
JOIN   departments AS d ON e.department_id = d.id
GROUP BY d.name
ORDER BY count DESC;

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

כלל הזהב

כאשר אתה משתמש ב-GROUP BY, כל עמודה ב-SELECT חייבת להיות:

  1. אחת מעמודות הקיבוץ (למשל department_id, d.name), או
  2. בתוך פונקציה מצטברת (למשל AVG(salary), COUNT(*)).
SQL
-- ERROR: first_name is neither in GROUP BY nor inside an aggregate
SELECT department_id, first_name, AVG(salary)
FROM   employees
GROUP BY department_id;

PostgreSQL מחזיר שגיאה מפורשת ("העמודה " חייבת להופיע ב-GROUP BY סעיף או לשמש בפונקציה מצטברת"). זה שבועות מוקדמים שכיח טעות: אם אתה רואה את זה, עצור ושאל את עצמך "מה הערך של first_name לקבוצה של 3 אנשים?" - אין תשובה אחת, ו בגלל זה המנוע מסרב.

נסה את זה

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

עבור כל מחלקה, חשב כמה עובדים היא מכילה. החזר שתי עמודות: שם המחלקה (שם מחלקות) וספירת העובדים. שורה אחת לכל מחלקה.

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

צבר עם COUNT(*) וקבץ לפי d.name. ה-SELECT חייב להכיל רק את עמודת הקיבוץ ואת המצטבר.

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

סקירת התרגיל

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

עבור כל מחלקה (departments.name), חשב את השכר הממוצע (AVG(salary)) של עובדיה, ממוין מהגבוה לנמוך.

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

AVG(e.salary) כמצטבר, GROUP BY d.name, ORDER BY DESC ממוצע.

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