MySQL: شرح مفصل لدوال التجميع في MySQL وعبارة GROUP BY

آخر تحديث: 2026-08-26

تُعد دوال التجميع جوهر تحليل البيانات — فالإحصاءات والتجميع والتلخيص تعتمد جميعها عليها.

يقدم هذا الدرس شرحًا متعمقًا لدوال التجميع والاستعلامات المجمعة.

100%
graph TB
    A[Aggregate Query Process] --> B[FROM Data Sources]
    B --> C[WHERE Filter Rows]
    C --> D[GROUP BY Grouping]
    D --> E[Aggregate Functions<br/>COUNT/SUM/AVG/MAX/MIN]
    E --> F[HAVING Filter Group]
    F --> G[SELECT Output]
    G --> H[ORDER BY Sort]
    H --> I[WITH ROLLUP Summary]

1. ما ستتعلمه



2. قصص حقيقية وراء الإحصاءات الواردة في التقرير

(1) المشكلة: برنامج Excel بطيء جدًّا في تحليل البيانات

يتعين على مدير العمليات تجميع إحصاءات عن عدد الموظفين في كل قسم، ومتوسط الرواتب، وأعلى راتب.

يتطلب استخدام برنامج Excel كتابة العديد من الصيغ، ويجب إعادة إجراء الحسابات كلما تم تحديث البيانات.

(2) حل الدوال التجميعية

SQL
SELECT 
    department,
    COUNT(*) AS emp_count,
    AVG(salary) AS avg_salary,
    MAX(salary) AS max_salary
FROM employees
GROUP BY department;


3. دوال التجميع

(1) العدد

SQL
-- Count the total number of lines
SELECT COUNT(*) FROM employees;

-- Count non-NULL rows
SELECT COUNT(email) FROM employees;

-- Count the number of unique entries
SELECT COUNT(DISTINCT department) FROM employees;
⚠️ ملاحظة: يقوم COUNT(*) بحساب جميع الصفوف، بينما يقوم COUNT(col) بحساب الصفوف التي لا تكون فيها قيمة «col» NULL.

(2) SUM/AVG: المجموع/المتوسط

SQL
-- Total Wages
SELECT SUM(salary) FROM employees;

-- Average Wage
SELECT AVG(salary) FROM employees;

-- Conditional Summation
SELECT SUM(amount) FROM orders WHERE status = 'paid';

(3) MAX/MIN الأقصى/الأدنى

SQL
-- Highest Salary
SELECT MAX(salary) FROM employees;

-- Minimum Wage
SELECT MIN(salary) FROM employees;

-- Earliest/Latest Date
SELECT MIN(hire_date) AS earliest, MAX(hire_date) AS latest FROM employees;


4. GROUP BY

▶ مثال: التجميع في حقل واحد

SQL
-- By Department
SELECT 
    department,
    COUNT(*) AS emp_count,
    AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
▶ جرّب الكود

الناتج:

TEXT 📖 للعرض فقط
+-------------+-----------+-----------+
| department  | emp_count | avg_salary|
+-------------+-----------+-----------+
| Engineering |        15 |   8500.00 |
| Sales       |        10 |   6000.00 |
| Marketing   |         8 |   5500.00 |
| HR          |         5 |   5000.00 |
+-------------+-----------+-----------+

▶ مثال: التجميع متعدد الحقول

SQL
-- By department and job title
SELECT 
    department,
    job_title,
    COUNT(*) AS count,
    AVG(salary) AS avg_salary
FROM employees
GROUP BY department, job_title
ORDER BY department, avg_salary DESC;
▶ جرّب الكود

▶ مثال: التجميع حسب التعبير

SQL
-- Orders by Year
SELECT 
    YEAR(order_date) AS year,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM orders
GROUP BY YEAR(order_date);

-- Statistics by Age Group
SELECT 
    CASE 
        WHEN age < 18 THEN 'Under 18'
        WHEN age BETWEEN 18 AND 30 THEN '18-30'
        WHEN age BETWEEN 31 AND 50 THEN '31-50'
        ELSE 'Over 50'
    END AS age_group,
    COUNT(*) AS count
FROM users
GROUP BY age_group;
▶ جرّب الكود

5. التصفية والتجميع في HAVING

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

▶ مثال: استخدام HAVING

SQL
-- Find the average wage > 6000 the department
SELECT 
    department,
    AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING avg_salary > 6000;

-- Find the number of orders > 10 's customers
SELECT 
    customer_id,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM orders
GROUP BY customer_id
HAVING order_count > 10;

-- WHERE + GROUP BY + HAVING Combination
SELECT 
    department,
    AVG(salary) AS avg_salary
FROM employees
WHERE hire_date >= '2024-01-01'  -- Filter the rows first
GROUP BY department               -- Regroup
HAVING avg_salary > 6000;        -- Final Filter Group
▶ جرّب الكود

6. ملخص باستخدام ROLLUP

▶ مثال: صفوف الملخص في ROLLUP

SQL
-- Automatically generate total rows
SELECT 
    department,
    COUNT(*) AS emp_count,
    SUM(salary) AS total_salary
FROM employees
GROUP BY department WITH ROLLUP;
▶ جرّب الكود

الناتج:

TEXT 📖 للعرض فقط
+-------------+-----------+--------------+
| department  | emp_count | total_salary |
+-------------+-----------+--------------+
| Engineering |        15 |    127500.00 |
| Sales       |        10 |     60000.00 |
| Marketing   |         8 |     44000.00 |
| HR          |         5 |     25000.00 |
| NULL        |        38 |    256500.00 |  -- Total
+-------------+-----------+--------------+


7. الدوال التجميعية والقيمة NULL

الدالة معالجة القيمة NULL
COUNT(*) يحتوي على صفوف NULL
COUNT(col) استبعاد القيم الفارغة
SUM(col) تجاهل القيمة NULL
AVG(col) تجاهل القيمة NULL (المقام لا يحتوي على قيمة NULL)
MAX(col) تجاهل القيمة NULL
MIN(col) تجاهل القيمة NULL

▶ مثال: التعامل مع القيم NULL

SQL
-- COUNT(*) vs COUNT(email)
SELECT 
    COUNT(*) AS total_rows,
    COUNT(email) AS has_email,
    COUNT(*) - COUNT(email) AS no_email
FROM users;

-- AVG Ignore NULL
SELECT AVG(salary) FROM employees;  -- NULL Not included in the calculation
▶ جرّب الكود

❓ أسئلة شائعة

س هل يمكن استخدام WHERE و HAVING معًا؟
ج نعم. ترتيب التنفيذ: WHERE (تصفية الصفوف) → GROUP BY (التجميع) → HAVING (تصفية المجموعات) → SELECT → ORDER BY.
س هل يجب تضمين الحقول الموجودة في جملة GROUP BY في جملة SELECT؟
ج في الوضع الصارم (Strict Mode) في MySQL، يجب تضمين الحقول غير التجميعية الموجودة في جملة SELECT في جملة GROUP BY.
س أيهما أسرع، COUNT(*) أم COUNT(1)؟
ج كلاهما بنفس السرعة. يقوم مُحسِّن MySQL تلقائيًا باختيار الطريقة الأفضل.
س هل يمكن تداخل الدوال التجميعية؟
ج لا يمكن تداخلها مباشرة AVG(SUM(...)). استخدم الاستعلامات الفرعية: SELECT AVG(total) FROM (SELECT SUM(amount) AS total FROM orders GROUP BY customer_id) t.

📖 ملخص


📝 تمارين

  1. المسألة الأساسية (الصعوبة: ⭐): احسب عدد الموظفين ومتوسط الراتب لكل قسم.

  2. مشكلة متقدمة (درجة الصعوبة ⭐⭐): حدد العملاء الذين يزيد إجمالي قيمة طلباتهم عن 10,000، وقم بفرزهم بترتيب تنازلي حسب إجمالي القيمة.

  3. التحدي (الصعوبة: ⭐⭐⭐): احسب عدد الطلبات، والمبلغ الإجمالي، ومتوسط المبلغ لكل شهر، واستخدم WITH ROLLUP لإضافة صفوف الملخص السنوي.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%