دروس الوحدة (3/4)
التجميع باستخدام GROUP BY
تعلمت في الوحدة 2 أن COUNT(*)، AVG(...)، SUM(...) تقلل من الكل
صفوف إلى صف نتيجة مفرد. ولكن ماذا لو كنت تريد راتبًا متوسطًا
لكل قسم، وليس للشركة بأكملها؟ تريد صفًا واحدًا per
مجموعة. هذه هي مهمة 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 مميز تم العثور عليه في
محمي_INLINE_6. ستحصل على 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 جملة أو يمكن استخدامها في وظيفة مجمعة"). إنها أسابيع مبكرة شائعة الخطأ: إذا رأيته توقف واسأل نفسك "ما قيمة محمي_INLINE_21 لمجموعة مكونة من 3 أشخاص؟" - لا توجد إجابة واحدة، و ولهذا السبب يرفض المحرك.
جربه
لكل قسم، احسب عدد الموظفين الموجود فيه. قم بإرجاع عمودين: اسم القسم (departments.name) وعدد الموظفين. صف واحد لكل قسم.
إظهار التلميح
التجميع باستخدام COUNT(*) والتجميع حسب d.name. يجب أن يحتوي التحديد على عمود التجميع والتجميع فقط.
الحل متاح بعد 3 من المحاولات
تمرين المراجعة
لكل قسم (departments.name)، قم بحساب متوسط الراتب (AVG(salary)) لموظفيه، مرتبة من الأعلى إلى الأدنى.
إظهار التلميح
متوسط (e.salary) كمجموع، GROUP BY d.name، ORDER BY متوسط DESC.
الحل متاح بعد 3 من المحاولات