الانتقال إلى المحتوى الرئيسي
الوحدة 3 · الدرس 3 من 411/57 في الدورة~10 min
دروس الوحدة (3/4)

التجميع باستخدام GROUP BY

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

جربه

تمرين#sql.m3.l3.e1
المحاولات: 0جارٍ التحميل…

لكل قسم، احسب عدد الموظفين الموجود فيه. قم بإرجاع عمودين: اسم القسم (departments.name) وعدد الموظفين. صف واحد لكل قسم.

جارٍ تحميل المحرر…
إظهار التلميح

التجميع باستخدام COUNT(*) والتجميع حسب d.name. يجب أن يحتوي التحديد على عمود التجميع والتجميع فقط.

الحل متاح بعد 3 من المحاولات

تمرين المراجعة

تمرين#sql.m3.l3.e2
المحاولات: 0جارٍ التحميل…

لكل قسم (departments.name)، قم بحساب متوسط ​​الراتب (AVG(salary)) لموظفيه، مرتبة من الأعلى إلى الأدنى.

جارٍ تحميل المحرر…
إظهار التلميح

متوسط ​​(e.salary) كمجموع، GROUP BY d.name، ORDER BY متوسط ​​DESC.

الحل متاح بعد 3 من المحاولات