دروس الوحدة (4/4)
مجموعات التصفية: تملك
بمجرد حصولك على نتيجة لكل مجموعة (الدرس السابق)، غالبًا ما تريد ذلك
** احتفظ فقط بالمجموعات التي تستوفي شرطًا **: الأقسام التي بها المزيد
أكثر من شخصين، مشاريع بميزانية متوسطة تزيد عن 100 ألف مستخدم
ما لا يقل عن 10 أوامر. للقيام بذلك WHERE ليس كافيًا.
لماذا أين لا يكفي
WHERE يقوم بتصفية صفوف الجدول، قبل التجميع. لذلك لا يمكن أن نرى
نتيجة COUNT(*) أو AVG(...): بحلول الوقت الذي يتم فيه تشغيل WHERE، تلك
القيم لم تحسب بعد
-- 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.
بناء الجملة
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column
HAVING condition_on_aggregate;-- 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 بتنفيذها عقليًا:
FROM/JOIN— ينشئ جدول البداية من خلال ضم المصادر.WHERE— يُسقط الصفوف التي لا تهتم بها.GROUP BY— يجمع الصفوف المتبقية في مجموعات.HAVING— يحذف المجموعات التي لا تهتم بها.SELECT— يحسب الأعمدة النهائية (بما في ذلك المجاميع).ORDER BY/LIMIT— إعادة الترتيب والقص.
ملاحظات هامة:
- في
WHEREيمكنك فقط استخدام أعمدة الجدول؛ - في
HAVINGيمكنك استخدام تجميع الأعمدة والتجميعات.
-- 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;جربه
لكل قسم، قم بإظهار الاسم (departments.name) وعدد الموظفين، ولكن فقط للأقسام التي تضم موظفين اثنين على الأقل. عمودين، صف واحد لكل قسم مؤهل.
إظهار التلميح
الشرط "2 على الأقل" يصبح COUNT(*) >= 2 في HAVING.
الحل متاح بعد 3 من المحاولات
تمرين المراجعة
إظهار الأقسام (departments.name) التي يتجاوز متوسط رواتبها 35000. خذ بعين الاعتبار فقط الموظفين المعينين من عام 2018 فصاعداً. عمودين: الاسم والمعدل. الترتيب حسب المتوسط تنازليا.
إظهار التلميح
حيث يقوم بتصفية الصفوف (الموظفون المعينون منذ عام 2018)، يقوم HAVING بتصفية المجموعات (المتوسط > 35000).
الحل متاح بعد 3 من المحاولات