MySQL: شرح مفصل لدوال التجميع في MySQL وعبارة GROUP BY
آخر تحديث: 2026-08-26
تُعد دوال التجميع جوهر تحليل البيانات — فالإحصاءات والتجميع والتلخيص تعتمد جميعها عليها.
يقدم هذا الدرس شرحًا متعمقًا لدوال التجميع والاستعلامات المجمعة.
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. ما ستتعلمه
- استخدام الدوال COUNT وSUM وAVG وMAX وMIN
- GROUP BY: الإحصائيات المجمعة
- وجود مجموعات التصفية
- مع صفوف الملخص التجميعي
- العلاقة بين الدوال التجميعية والقيمة NULL
2. قصص حقيقية وراء الإحصاءات الواردة في التقرير
(1) المشكلة: برنامج Excel بطيء جدًّا في تحليل البيانات
يتعين على مدير العمليات تجميع إحصاءات عن عدد الموظفين في كل قسم، ومتوسط الرواتب، وأعلى راتب.
يتطلب استخدام برنامج Excel كتابة العديد من الصيغ، ويجب إعادة إجراء الحسابات كلما تم تحديث البيانات.
(2) حل الدوال التجميعية
SELECT
department,
COUNT(*) AS emp_count,
AVG(salary) AS avg_salary,
MAX(salary) AS max_salary
FROM employees
GROUP BY department;
3. دوال التجميع
(1) العدد
-- 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: المجموع/المتوسط
-- 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 الأقصى/الأدنى
-- 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
▶ مثال: التجميع في حقل واحد
-- By Department
SELECT
department,
COUNT(*) AS emp_count,
AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
الناتج:
+-------------+-----------+-----------+
| department | emp_count | avg_salary|
+-------------+-----------+-----------+
| Engineering | 15 | 8500.00 |
| Sales | 10 | 6000.00 |
| Marketing | 8 | 5500.00 |
| HR | 5 | 5000.00 |
+-------------+-----------+-----------+
▶ مثال: التجميع متعدد الحقول
-- 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;
▶ مثال: التجميع حسب التعبير
-- 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
-- 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
-- Automatically generate total rows
SELECT
department,
COUNT(*) AS emp_count,
SUM(salary) AS total_salary
FROM employees
GROUP BY department WITH ROLLUP;
الناتج:
+-------------+-----------+--------------+
| 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
-- 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
❓ أسئلة شائعة
AVG(SUM(...)). استخدم الاستعلامات الفرعية: SELECT AVG(total) FROM (SELECT SUM(amount) AS total FROM orders GROUP BY customer_id) t.📖 ملخص
- COUNT/SUM/AVG/MAX/MIN هي الدوال التجميعية الخمس الرئيسية
- GROUP BY: التجميع حسب الحقل؛ يمكن الجمع بين عدة حقول
- HAVING تُستخدم للتصفية حسب المجموعة (يمكن استخدام دوال التجميع)، WHERE تُستخدم للتصفية حسب الصف (لا يمكن استخدام دوال التجميع)
- مع التجميع: يقوم تلقائيًا بإنشاء صفوف ملخصية
- يتم تجاهل NULL في دوال التجميع (باستثناء COUNT(*))
📝 تمارين
-
المسألة الأساسية (الصعوبة: ⭐): احسب عدد الموظفين ومتوسط الراتب لكل قسم.
-
مشكلة متقدمة (درجة الصعوبة ⭐⭐): حدد العملاء الذين يزيد إجمالي قيمة طلباتهم عن 10,000، وقم بفرزهم بترتيب تنازلي حسب إجمالي القيمة.
-
التحدي (الصعوبة: ⭐⭐⭐): احسب عدد الطلبات، والمبلغ الإجمالي، ومتوسط المبلغ لكل شهر، واستخدم
WITH ROLLUPلإضافة صفوف الملخص السنوي.