שיעורי מודול (3/4)
קיבוץ עם GROUP BY
במודול 2 למדת שCOUNT(*), AVG(...), SUM(...) מפחיתים את כל
שורות לשורת תוצאה יחידה. אבל מה אם אתה רוצה משכורת ממוצעת
לכל מחלקה, לא לכל החברה? אתה רוצה שורה אחת לכל
קבוצה. זה התפקיד של GROUP BY.
התחביר
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column;קרא באנגלית: "חלק את השורות לקבוצות שחולקות את אותו ערך של
grouping_column, ולכל קבוצה מחשב את המצטבר".
-- 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:
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 חייבת להיות:
- אחת מעמודות הקיבוץ (למשל
department_id,d.name), או - בתוך פונקציה מצטברת (למשל
AVG(salary),COUNT(*)).
-- 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 אנשים?" - אין תשובה אחת, ו
בגלל זה המנוע מסרב.
נסה את זה
עבור כל מחלקה, חשב כמה עובדים היא מכילה. החזר שתי עמודות: שם המחלקה (שם מחלקות) וספירת העובדים. שורה אחת לכל מחלקה.
הצג רמז
צבר עם COUNT(*) וקבץ לפי d.name. ה-SELECT חייב להכיל רק את עמודת הקיבוץ ואת המצטבר.
הפתרון זמין לאחר 3 ניסיונות
סקירת התרגיל
עבור כל מחלקה (departments.name), חשב את השכר הממוצע (AVG(salary)) של עובדיה, ממוין מהגבוה לנמוך.
הצג רמז
AVG(e.salary) כמצטבר, GROUP BY d.name, ORDER BY DESC ממוצע.
הפתרון זמין לאחר 3 ניסיונות