الفرق بين HAVING و WHERE في SQL

كلا من HAVING و WHERE تُستخدمان في SQL لتصفية البيانات (Filter)، لكن الفرق الأساسي بينهما يكمن في التوقيت الذي يتم فيه تطبيق الشرط أثناء تنفيذ الاستعلام وكيفية التعامل مع البيانات المجمعة (Aggregated Data).


الفرق الرئيسي باختصار

  1. WHERE:
    • تُستخدم لتصفية الصفوف قبل عمليات التجميع (مثل GROUP BY).
    • تعمل على البيانات الأصلية في الجدول.
  2. HAVING:
    • تُستخدم لتصفية النتائج بعد عمليات التجميع.
    • تعمل على البيانات المجمعة باستخدام دوال التجميع (مثل SUM, AVG, COUNT).

تفاصيل الفرق بين WHERE و HAVING

1. WHERE

  • تُستخدم لتحديد الصفوف التي سيتم تضمينها في نتيجة الاستعلام.
  • يتم تطبيقها قبل تطبيق أي عمليات تجميع أو ترتيب (GROUP BY أو ORDER BY).
  • لا يمكن استخدام دوال التجميع (مثل SUM أو AVG) داخل WHERE.

مثال على WHERE:

SELECT ProductID, Price 
FROM Products
WHERE Price > 100;
  • يتم تصفية الصفوف بناءً على الشرط Price > 100.
  • هذا يحدث قبل أي عملية تجميع.

2. HAVING

  • تُستخدم لتصفية البيانات بعد تطبيق عمليات التجميع (GROUP BY).
  • يمكن استخدامها مع دوال التجميع مثل SUM, COUNT, AVG, إلخ.
  • تُطبق فقط على النتائج المجمعة.

مثال على HAVING:

SELECT Category, SUM(Price) AS TotalPrice
FROM Products
GROUP BY Category
HAVING SUM(Price) > 500;
  • هنا:
    • يتم تجميع البيانات حسب Category باستخدام GROUP BY.
    • يتم تطبيق الشرط HAVING SUM(Price) > 500 على النتائج المجمعة.

متى نستخدم WHERE و HAVING؟

الحالةنستخدم WHEREنستخدم HAVING
تصفية الصفوف قبل التجميعنعملا
تصفية النتائج المجمعة (بعد GROUP BY)لانعم
استخدام دوال التجميع (مثل SUM و COUNT)غير ممكنممكن

مثال يجمع بين WHERE و HAVING

لنفترض أننا نريد معرفة مجموع الأسعار للمنتجات في كل فئة (Category) بشرط أن:

  1. المنتجات ذات سعر أعلى من 100 فقط سيتم أخذها في الاعتبار.
  2. مجموع الأسعار للفئة يجب أن يكون أكبر من 500.

SQL Query:

SELECT Category, SUM(Price) AS TotalPrice
FROM Products
WHERE Price > 100
GROUP BY Category
HAVING SUM(Price) > 500;

شرح الكود:

  1. WHERE Price > 100:
    • تصفية الصفوف بحيث تُستبعد المنتجات التي سعرها أقل من 100 قبل عملية التجميع.
  2. GROUP BY Category:
    • يتم تجميع الصفوف بناءً على كل فئة.
  3. HAVING SUM(Price) > 500:
    • تصفية النتائج بعد التجميع بحيث يتم تضمين فقط الفئات التي مجموع أسعار منتجاتها أكبر من 500.

رسم توضيحي للفرق

Step 1: WHERE            Step 2: GROUP BY          Step 3: HAVING
+--------+--------+      +--------+--------+      +--------+--------+
| Product| Price  |      | Category | SUM(Price)|      | Category | SUM(Price)|
+--------+--------+      +--------+--------+      +--------+--------+
| P1     | 150    |      |   Cat1   |   550    |      |   Cat1   |   550    |
| P2     | 200    |      |   Cat2   |   300    |      |   Cat3   |   600    |
| P3     | 100    |      |   Cat3   |   600    |      +--------------------+
| P4     | 250    |
+--------+--------+
  • الـWHERE: تُزيل P3 (Price = 100).
  • الـGROUP BY: تُجمع البيانات حسب الفئات (Category).
  • الـHAVING: تُبقي فقط النتائج المجمعة التي تحقق الشرط SUM(Price) > 500.

الملخص

  • WHERE:
    • تُستخدم لتصفية البيانات قبل عمليات التجميع.
    • لا تُدعم دوال التجميع.
  • HAVING:
    • تُستخدم لتصفية البيانات بعد عمليات التجميع.
    • تُدعم دوال التجميع.

القاعدة الذهبية:

  • إذا كنت تُصفّي البيانات قبل التجميع، استخدم WHERE.
  • إذا كنت تُصفّي البيانات بعد التجميع، استخدم HAVING.