الـ CASE Statement في SQL هي أداة قوية بتستخدم لتنفيذ شرط معين وإرجاع قيمة بناءً على تحقق الشرط. بتعتبر زي if-else في لغات البرمجة.

بتستخدم غالبًا في الاستعلامات لتعديل أو تخصيص النتائج بناءً على شروط محددة.


الصيغة العامة للـ CASE Statement:

1. CASE بسيط (Simple CASE):

بيستخدم لمقارنة قيمة معينة بعدة احتمالات.

CASE expression
    WHEN value1 THEN result1
    WHEN value2 THEN result2
    ...
    ELSE default_result
END

2. CASE مع شروط (Searched CASE):

بيسمح باستخدام شروط بدل من مقارنة قيمة مباشرة.

CASE 
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ...
    ELSE default_result
END

Examples

1. CASE بسيط:

لو عندك جدول employees وعمود job_title وعايز تعرض وصف بسيط لكل وظيفة:

SELECT name,
       job_title,
       CASE job_title
           WHEN 'Manager' THEN 'Leads the team'
           WHEN 'Developer' THEN 'Writes code'
           WHEN 'Analyst' THEN 'Analyzes data'
           ELSE 'Other'
       END AS job_description
FROM employees;

2. CASE مع شروط:

لو عايز تصنف الموظفين بناءً على مرتباتهم:

SELECT name,
       salary,
       CASE 
           WHEN salary > 10000 THEN 'High Salary'
           WHEN salary BETWEEN 5000 AND 10000 THEN 'Medium Salary'
           ELSE 'Low Salary'
       END AS salary_category
FROM employees;

3. CASE داخل GROUP BY أو ORDER BY:

تقدر تستخدم الـ CASE لترتيب النتائج بطريقة مخصصة. مثلاً ترتيب الموظفين حسب المرتب لكن بأولوية لمجموعات معينة:

SELECT name, salary
FROM employees
ORDER BY 
    CASE 
        WHEN salary > 10000 THEN 1
        WHEN salary BETWEEN 5000 AND 10000 THEN 2
        ELSE 3
    END;

More Examples

1. In CASE you need to aggregate

استخدام CASE داخل دوال تجميع زي SUM أو COUNT لتصفية البيانات بناءً على شروط معينة.

SELECT 
    SUM(CASE WHEN status = 'Active' THEN salary ELSE 0 END) AS total_active_salary,
    SUM(CASE WHEN status = 'Inactive' THEN salary ELSE 0 END) AS total_inactive_salary
FROM employees;
  • الشرح: بيجمع الرواتب بناءً على حالة الموظف (Active أو Inactive).

2. COUNTing CASES

استخدام CASE مع COUNT لحساب عدد القيم بناءً على شروط محددة.

SELECT 
    COUNT(CASE WHEN status = 'Active' THEN 1 END) AS active_count,
    COUNT(CASE WHEN status = 'Inactive' THEN 1 END) AS inactive_count
FROM employees;
  • الشرح: بيعد عدد الموظفين الـ Active والـ Inactive.

3. CASE WHEN with COUNT

مشابه للمثال السابق لكنه ممكن يشمل استخدام GROUP BY.

SELECT department_id,
       COUNT(CASE WHEN status = 'Active' THEN 1 END) AS active_count
FROM employees
GROUP BY department_id;
  • الشرح: بيحسب عدد الموظفين الـ Active في كل قسم.

4. CASE WHEN with SUM

استخدام CASE مع SUM لتجميع قيم عمود معين بناءً على شرط.

SELECT department_id,
       SUM(CASE WHEN status = 'Active' THEN salary ELSE 0 END) AS total_active_salary
FROM employees
GROUP BY department_id;
  • الشرح: بيجمع رواتب الموظفين الـ Active لكل قسم.

5. The CASE is fairly AVG… SELECT

استخدام CASE مع AVG لحساب متوسط القيم بناءً على شرط.

SELECT 
    AVG(CASE WHEN status = 'Active' THEN salary END) AS avg_active_salary,
    AVG(CASE WHEN status = 'Inactive' THEN salary END) AS avg_inactive_salary
FROM employees;
  • الشرح: بيحسب متوسط رواتب الموظفين بناءً على حالتهم.

6. A ROUNDED AVG

حساب متوسط القيم مع تقريب الناتج باستخدام ROUND.

SELECT 
    ROUND(AVG(CASE WHEN status = 'Active' THEN salary END), 2) AS avg_active_salary
FROM employees;
  • الشرح: بيحسب متوسط رواتب الموظفين الـ Active ويقرب الناتج لعشريتين.

7. Percentages with CASE and AVG

حساب نسب مئوية باستخدام CASE مع AVG.

SELECT 
    department_id,
    100.0 * AVG(CASE WHEN status = 'Active' THEN 1 ELSE 0 END) AS active_percentage
FROM employees
GROUP BY department_id;
  • الشرح: بيحسب نسبة الموظفين الـ Active في كل قسم.

استخدام الـ CASE مع التحديث (UPDATE):

ممكن تستخدمه لتحديث بيانات بناءً على شروط:

UPDATE employees
SET bonus = 
    CASE 
        WHEN salary > 10000 THEN 1000
        WHEN salary BETWEEN 5000 AND 10000 THEN 500
        ELSE 200
    END;

Nested CASE Statement في SQL

الـ Nested CASE هو لما تستخدم CASE جوه CASE، وده بيكون مفيد لما تحتاج منطق أكتر تعقيدًا أو شروط متداخلة.


الصيغة العامة لـ Nested CASE:

CASE
    WHEN condition1 THEN
        CASE
            WHEN nested_condition1 THEN result1
            WHEN nested_condition2 THEN result2
            ELSE nested_default
        END
    WHEN condition2 THEN result3
    ELSE default_result
END

أمثلة على Nested CASE:

1. تصنيف البيانات بناءً على شروط متداخلة:

لو عندك جدول اسمه students وفيه الأعمدة grade و attendance، وعايز تصنف الطلاب حسب الدرجة وإذا كانوا مواظبين أو لأ:

SELECT
    student_id,
    CASE
        WHEN grade >= 90 THEN
            CASE
                WHEN attendance >= 80 THEN 'Excellent with Good Attendance'
                ELSE 'Excellent but Poor Attendance'
            END
        WHEN grade >= 70 THEN
            CASE
                WHEN attendance >= 80 THEN 'Good with Good Attendance'
                ELSE 'Good but Poor Attendance'
            END
        ELSE 'Needs Improvement'
    END AS performance
FROM students;
  • الشرح:
    • لو الدرجة (grade) أكبر من أو تساوي 90:
      • يتم فحص المواظبة (attendance): لو 80 أو أكتر النتيجة “Excellent with Good Attendance”، وإلا “Excellent but Poor Attendance”.
    • لو الدرجة بين 70 و90، نفس المنطق يتكرر.
    • لو أقل من 70، النتيجة “Needs Improvement”.

2. Nested CASE مع أرقام:

لو عندك جدول orders وعايز تحدد حالة الطلب بناءً على quantity وprice:

SELECT
    order_id,
    CASE
        WHEN quantity > 100 THEN
            CASE
                WHEN price > 500 THEN 'Bulk Order - High Value'
                ELSE 'Bulk Order - Low Value'
            END
        WHEN quantity > 50 THEN
            CASE
                WHEN price > 500 THEN 'Medium Order - High Value'
                ELSE 'Medium Order - Low Value'
            END
        ELSE 'Small Order'
    END AS order_category
FROM orders;
  • الشرح:
    • لو الكمية أكبر من 100:
      • السعر (price) يتحدد إذا كان أعلى من 500 (High Value) أو أقل (Low Value).
    • الكمية بين 50 و100 بنفس المنطق.
    • الكمية أقل من أو تساوي 50 هي “Small Order”.

3. Nested CASE لتصنيف النصوص:

لو عندك جدول employees وعايز تصنف الموظفين حسب الوظيفة (job_title) والقسم (department):

SELECT
    employee_id,
    CASE
        WHEN job_title = 'Manager' THEN
            CASE
                WHEN department = 'HR' THEN 'HR Manager'
                WHEN department = 'IT' THEN 'IT Manager'
                ELSE 'Other Manager'
            END
        WHEN job_title = 'Developer' THEN
            CASE
                WHEN department = 'IT' THEN 'Software Developer'
                WHEN department = 'Web' THEN 'Web Developer'
                ELSE 'Other Developer'
            END
        ELSE 'Other Role'
    END AS role_description
FROM employees;
  • الشرح:
    • لو الموظف “Manager”، القسم يحدد النوع (HR Manager, IT Manager).
    • لو “Developer”، القسم يحدد النوع (Software Developer, Web Developer).
    • أي وظيفة تانية تصنف كـ “Other Role”.

ملاحظات:

  1. الـNested CASE بيبقى مفيد للمنطق المعقد، لكن ممكن يصعب قراءة الكود لو كان متداخل جدًا.
  2. حاول تنظم الكود باستخدام Tab أو Indentation لتحسين وضوحه.
  3. لو المنطق بقى معقد جدًا، فكر في تقسيمه لاستعلامات أصغر.

الخلاصة:

  • الـ Nested CASE بيديك مرونة أكتر في التعامل مع شروط متعددة.
  • مفيد جدًا في الحالات اللي فيها شروط مترابطة أو تعتمد على بعضها.
  • بس تأكد دايمًا إن الكود منظم وسهل القراءة.

نقاط مهمة:

  1. الـCASE لازم ينتهي بـ END.
  2. يمكن استخدام ELSE كخيار افتراضي لو مفيش شرط تحقق.
  3. يمكن تضمين أكثر من CASE Statement في نفس الاستعلام.
  4. الـ CASE يمكن استخدامها في أي مكان في الاستعلام: SELECT, WHERE, GROUP BY, HAVING, ORDER BY.

خلاصة:

الـ CASE Statement أداة مرنة بتساعدك تضيف منطق شرطي لاستعلامات SQL. سواء بتستخدمها للتصنيف، الترتيب، أو تحديث البيانات، هتكون مفيدة جدًا لإدارة البيانات بناءً على شروط معينة.