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

مجموعات التصفية: تملك

بمجرد حصولك على نتيجة لكل مجموعة (الدرس السابق)، غالبًا ما تريد ذلك ** احتفظ فقط بالمجموعات التي تستوفي شرطًا **: الأقسام التي بها المزيد أكثر من شخصين، مشاريع بميزانية متوسطة تزيد عن 100 ألف مستخدم ما لا يقل عن 10 أوامر. للقيام بذلك WHERE ليس كافيًا.

لماذا أين لا يكفي

WHERE يقوم بتصفية صفوف الجدول، قبل التجميع. لذلك لا يمكن أن نرى نتيجة COUNT(*) أو AVG(...): بحلول الوقت الذي يتم فيه تشغيل WHERE، تلك القيم لم تحسب بعد

SQL
-- ERROR: COUNT(*) doesn't exist yet when WHERE is evaluated
SELECT department_id, COUNT(*) AS count
FROM   employees
WHERE  COUNT(*) > 2     -- ❌ doesn't work
GROUP BY department_id;

لتصفية بعد التجميع، هناك عبارة مخصصة: HAVING.

بناء الجملة

SQL
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM   table
GROUP BY grouping_column
HAVING   condition_on_aggregate;
SQL
-- Departments with more than 2 employees:
SELECT department_id, COUNT(*) AS count
FROM   employees
GROUP BY department_id
HAVING   COUNT(*) > 2;

HAVING هو GROUP BY ما هو WHERE هو FROM: نفس الفكرة ("عامل التصفية")، ولكن يتم تطبيقه بعد التجميع، على الإجمالي.

الترتيب المنطقي للجمل

لكي لا تخلط بين WHERE وHAVING مرة أخرى، تذكر الترتيب الذي تم به يقوم SQL بتنفيذها عقليًا:

  1. FROM / JOIN — ينشئ جدول البداية من خلال ضم المصادر.
  2. WHERE — يُسقط الصفوف التي لا تهتم بها.
  3. GROUP BY — يجمع الصفوف المتبقية في مجموعات.
  4. HAVING — يحذف المجموعات التي لا تهتم بها.
  5. SELECT — يحسب الأعمدة النهائية (بما في ذلك المجاميع).
  6. ORDER BY / LIMIT — إعادة الترتيب والقص.

ملاحظات هامة:

  • في WHERE يمكنك فقط استخدام أعمدة الجدول؛
  • في HAVING يمكنك استخدام تجميع الأعمدة والتجميعات.
SQL
-- Classic combo: filter first, group, filter the groups, sort.
SELECT d.name, AVG(e.salary) AS average
FROM   employees   AS e
JOIN   departments AS d ON e.department_id = d.id
WHERE  e.hired_on >= '2018-01-01'   -- filter rows
GROUP BY d.name
HAVING   AVG(e.salary) > 35000      -- filter groups
ORDER BY average DESC;

جربه

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

لكل قسم، قم بإظهار الاسم (departments.name) وعدد الموظفين، ولكن فقط للأقسام التي تضم موظفين اثنين على الأقل. عمودين، صف واحد لكل قسم مؤهل.

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

الشرط "2 على الأقل" يصبح COUNT(*) >= 2 في HAVING.

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

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

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

إظهار الأقسام (departments.name) التي يتجاوز متوسط ​​رواتبها 35000. خذ بعين الاعتبار فقط الموظفين المعينين من عام 2018 فصاعداً. عمودين: الاسم والمعدل. الترتيب حسب المتوسط ​​تنازليا.

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

حيث يقوم بتصفية الصفوف (الموظفون المعينون منذ عام 2018)، يقوم HAVING بتصفية المجموعات (المتوسط ​​> 35000).

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