انتقل إلى محتوى الدرس
الدرس 33
دورة MySQL

المجاميع الفرعية عبر ROLLUP والترتيب المنطقي لتنفيذ الاستعلامMySQL Summary Subtotals with ROLLUP and Query Execution Order

تعلّم المجاميع الفرعية عبر ROLLUP والترتيب المنطقي لتنفيذ الاستعلام بأسلوب MySQL 8 الحديث مع أمثلة استعلامات SQL وتطبيقات تفاعلية.
أقسام الدرس
6
الأمثلة
6
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
8
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع
أضف صفوف المجموع العام والمجاميع الفرعية تلقائياً إلى استعلامات GROUP BY باستخدام ميزة WITH ROLLUP.

تتطلب معظم التقارير المالية والإدارية عرض مجاميع كل فئة متبوعةً بصف المجموع العام الكلي في نهاية التقرير. بدلاً من تنفيذ استعلامين منفصلين، يمكنك إلحاق العبارة WITH ROLLUP مباشرةً بعد جملة GROUP BY.

  • صف التجميع الفائق (Super-Aggregate): عند التجميع بعمود واحد مثل GROUP BY category WITH ROLLUP، يعرض MySQL صفوف الفئات المعتادة ثم يضيف صفاً أخيراً يمثّل الإجمالي العام لكل الفئات.
  • علامة NULL في عمود التجميع: يضع المحرك القيمة NULL في عمود التجميع داخل صف المجموع العام، بينما تعرض الدوال التجميعية COUNT و SUM و AVG حصيلة الجدول الكلي.

يحسب محرك MySQL صفوف WITH ROLLUP أثناء المسحة التجميعية نفسها دون إعادة قراءة الجدول من القرص.

المجاميع التراكمية WITH ROLLUP ودالة GROUPING وترتيب تنفيذ الاستعلام

مسار التنفيذ المنطقي: 1. FROM ثم 2. WHERE ثم 3. GROUP BY ثم 4. HAVING ثم 5. SELECT ثم 6. DISTINCT ثم 7. ORDER BY ثم 8. LIMIT
مخطط توضيحي لدرس المجاميع الفرعية عبر ROLLUP والترتيب المنطقي لتنفيذ الاستعلام
مخطط توضيحي لدرس المجاميع الفرعية عبر ROLLUP والترتيب المنطقي لتنفيذ الاستعلام
SQL
-- Category totals plus automatic Grand Total row at the end
SELECT category,
       COUNT(*)       AS items_count,
       SUM(stock_qty) AS total_units
FROM products
WHERE is_active = 1
GROUP BY category WITH ROLLUP;
افهم كيف يولّد WITH ROLLUP مجاميع فرعية متدرجة من اليمين إلى اليسار عند التجميع بعدة أعمدة.

عند التجميع بعدة أعمدة، يولّد WITH ROLLUP المجاميع الفرعية تدريجياً من اليمين إلى اليسار عبر مستويات الهرم التجميعي:

  • المستوى الأول (صفوف التفصيل): في GROUP BY region, city WITH ROLLUP تظهر أولاً مجاميع كل مدينة داخل إقليمها.
  • المستوى الثاني (المجموع الفرعي للإقليم): يتحول العمود الأيمن city إلى NULL لإنتاج صف المجموع الفرعي الخاص بكل إقليم (region, NULL).
  • المستوى الثالث (المجموع العام الكلي): في النهاية يتحول العمودان معاً إلى (NULL, NULL) لإنتاج صف المجموع العام الكلي لجميع الأقاليم والمدن!

لذلك احرص دائماً على ترتيب أعمدة GROUP BY من المستوى الأوسع (كالإقليم أو السنة) على اليسار إلى المستوى الأدق (كالمدينة أو الشهر) على اليمين.

SQL
-- Multi-level rollup: per (dept, role), per dept, and grand total
SELECT dept_id,
       job_role,
       COUNT(*)    AS headcount,
       SUM(salary) AS payroll_usd
FROM employees
WHERE is_active = 1
GROUP BY dept_id, job_role WITH ROLLUP;
استخدم الدالة القياسية GROUPING(col) في MySQL 8 للتفريق بين قيم NULL الحقيقية وصفوف المجاميع الناتجة عن ROLLUP.

ماذا يحدث إذا كان عمود التجميع نفسه يقبل القيم الفارغة ويحتوي فعلياً على صفوف NULL في الجدول؟ سيظهر NULL في صف البيانات الفعلي وفي صف المجموع العام معاً! يعالج MySQL 8 هذا الالتباس عبر الدالة القياسية GROUPING(expr):

  • القيمة 0: تعني أن الصف يمثّل مجموعة بيانات عادية (حتى لو كانت قيمة العمود الأصلية المسجلة في الجدول هي NULL).
  • القيمة 1: تعني أن القيمة NULL الظاهرة في العمود هي علامة مجموع فرعي أو كلي ولّدتها ميزة WITH ROLLUP.

يمكنك استخدام GROUPING(col) في قائمة SELECT أو في ORDER BY لدفع صفوف المجاميع إلى النهاية دائماً، أو داخل HAVING لاستخراج صفوف المجاميع الفرعية فقط.

SQL
-- Distinguish real NULLs (0) from ROLLUP subtotal rows (1)
SELECT dept_id,
       job_role,
       GROUPING(dept_id)  AS is_grand_total,
       GROUPING(job_role) AS is_dept_subtotal,
       SUM(salary)        AS total_salary
FROM employees
GROUP BY dept_id, job_role WITH ROLLUP;
أتقن الفرق الجوهري بين الترتيب النحوي لكتابة جمل SQL والترتيب المنطقي الفعلي لتنفيذها داخل المحرك.

من أهم المفاهيم الهندسية لإتقان SQL إدراك أن محرك قاعدة البيانات لا ينفّذ جمل الاستعلام بالترتيب الذي تُكتب به:

  • الترتيب النحوي المكتوب: يبدأ بـ SELECT ثم FROM ثم WHERE ثم GROUP BY ثم HAVING ثم ORDER BY وأخيراً LIMIT.
  • الترتيب المنطقي للتنفيذ الفعلي: يبدأ بـ 1. FROM (تحديد الجدول) ← 2. WHERE (تصفية الصفوف) ← 3. GROUP BY (تجميع المجموعات) ← 4. HAVING (تصفية المجموعات) ← 5. SELECT (حساب الأعمدة والأسماء المستعارة) ← 6. DISTINCT (إزالة التكرار) ← 7. ORDER BY (الفرز) ← 8. LIMIT / OFFSET (اقتطاع الصفحة).

يفسّر هذا التسلسل المنطقي ذو المراحل الثماني جميع القواعد السلوكية التي تعلّمتها في وحدتي التصفية والتجميع.

SQL
-- Every clause written in lexical order, executed 1..8 logically
SELECT DISTINCT category,
       COUNT(*)       AS item_cnt,
       SUM(stock_qty) AS total_stock
FROM products
WHERE is_active = 1
GROUP BY category
HAVING COUNT(*) >= 2
ORDER BY total_stock DESC
LIMIT 5 OFFSET 0;
تتبّع بدقة الجمل التي يمكنها رؤية الأسماء المستعارة المعرّفة في SELECT والجمل التي لا يمكنها ذلك.

بما أن الأسماء المستعارة للأعمدة AS alias_name تُعرَّف في مرحلة SELECT (المرحلة الخامسة في التنفيذ المنطقي)، فإن صلاحية استخدامها في بقية جمل الاستعلام تخضع لقواعد واضحة:

  • ممنوعة قطعياً في WHERE (المرحلة 2): عند تنفيذ WHERE لم تكن مرحلة SELECT قد بدأت بعد، لذا فإن استخدام الاسم المستعار داخل WHERE يُطلق دائماً الخطأ Error 1054: Unknown column.
  • مدعومة قياسياً في ORDER BY (المرحلة 7): تعمل الأسماء المستعارة في ORDER BY في جميع قواعد البيانات لأن الفرز يتم بعد اكتمال SELECT.
  • امتداد MySQL في GROUP BY و HAVING: يدعم محرك MySQL كامتداد مريح التعرّف على الأسماء المستعارة داخل GROUP BY و HAVING أيضاً.

معرفة هذه القاعدة تختصر وقت تشخيص أخطاء الأعمدة غير المعروفة في الاستعلامات التحليلية.

SQL
-- WHERE uses raw expression; GROUP BY, HAVING & ORDER BY use alias
SELECT (unit_price - discount_usd) AS net_price,
       COUNT(*)                    AS item_count
FROM products
WHERE (unit_price - discount_usd) > 0
GROUP BY net_price
HAVING item_count >= 2
ORDER BY net_price DESC;
جدول مرجعي شامل للمراحل الثماني لتنفيذ استعلام SELECT في MySQL 8 مع صلاحية الأسماء المستعارة.

يلخّص الجدول التالي المراحل الثماني للتنفيذ المنطقي لاستعلام SELECT في MySQL 8 مرتبةً حسب تسلسل تنفيذها الفعلي داخل المحرك:

ترتيب التنفيذجملة SQLالوظيفة الأساسية للمرحلةهل ترى أسماء SELECT المستعارة؟
1FROMتحديد الجدول المصدر والأسماء المستعارة للجداوللا
2WHEREتصفية الصفوف الفردية الخام قبل التجميعلا (تُطلق خطأ 1054)
3GROUP BY [WITH ROLLUP]تقسيم المجموعات وتوليد المجاميع التراكميةنعم (ميزة في MySQL)
4HAVINGتصفية المجموعات بناءً على نتائج الدوال التجميعيةنعم (ميزة في MySQL)
5SELECTحساب التعابير والدوال وتعريف الأسماء المستعارة للأعمدةتُعرَّف في هذه المرحلة
6DISTINCTإزالة الصفوف المتطابقة المكررة من النتيجةنعم
7ORDER BYترتيب الصفوف النهائية تصاعدياً أو تنازلياًنعم (قياسي عالمياً)
8LIMIT / OFFSETاقتطاع شريحة الصفحة المطلوبة وإرسالها للعميلتقبل أعداداً صحيحة

ملخص الدرس: أتقنت في هذا الدرس توليد المجاميع الفرعية والعامة عبر WITH ROLLUP، وتمييز صفوف المجموع التراكمي بدالة GROUPING()، وفهم المسار المنطقي الكامل لتنفيذ استعلامات SQL من FROM حتى LIMIT.
الخطوة التالية والدرس القادم: ننتقل في الوحدة القادمة (الدوال المدمجة Built-In Functions) إلى معالجة النصوص والأرقام والتواريخ والتعابير الشرطية في MySQL 8.

SQL
-- Complete rollup report sorted with grand total last
SELECT dept_id,
       GROUPING(dept_id) AS is_grand_total,
       COUNT(*)          AS staff_count,
       SUM(salary)       AS dept_payroll
FROM employees
WHERE is_active = 1
GROUP BY dept_id WITH ROLLUP
ORDER BY GROUPING(dept_id) ASC, dept_id ASC;
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

أتقنّا في هذا الدرس المجاميع الفرعية عبر ROLLUP والترتيب المنطقي لتنفيذ الاستعلام في MySQL 8 مع أمثلة عملية.

الخطوة التالية والدرس القادم

أكمل التدريبات والاختبار التفاعلي أدناه قبل الانتقال إلى الدرس التالي في مسار MySQL.

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 WITH ROLLUP معدِّل المجاميع الفرعية WITH ROLLUP
إضافة لجملة GROUP BY تولّد تلقائياً صفوف المجاميع الفرعية وصف المجموع العام الكلي من اليمين إلى اليسار.
للمراجعة
02 GROUPING() Function دالة تمييز التجميع GROUPING()
دالة قياسية في MySQL 8 تُعيد 1 إذا كانت قيمة NULL ناتجة عن صف مجموع ROLLUP وتُعيد 0 للصفوف العادية.
للمراجعة
03 Super-Aggregate Row صف التجميع الفائق (Super-Aggregate Row)
صف إحصائي يولّده WITH ROLLUP لجمع نتائج المجموعات الفرعية وعرض المجموع الفرعي أو العام.
للمراجعة
04 Logical Query Execution Order الترتيب المنطقي لتنفيذ الاستعلام
التسلسل المنطقي الفعلي لتنفيذ مراحل الاستعلام بدءاً من FROM ثم WHERE ثم GROUP BY ثم HAVING ثم SELECT ثم ORDER BY و LIMIT.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 OLAP OLAP
Online Analytical Processing
المعالجة التحليلية الفورية للبيانات التي تعتمد على المجاميع الهرمية مثل WITH ROLLUP
للمراجعة
02 SQL SQL
Structured Query Language
لغة الاستعلامات البنيوية القياسية
للمراجعة
03 ISO ISO
International Organization for Standardization
المنظمة الدولية للمعايير المعتمدة لدالة GROUPING() وترتيب تنفيذ الاستعلام
للمراجعة
04 DBMS DBMS
Database Management System
نظام إدارة قواعد البيانات المسؤول عن تحليل وتنفيذ خطة الاستعلام
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. اكتب استعلام SELECT على جدول products يعرض category و COUNT(*) باسم item_count و SUM(stock_qty) باسم total_stock مجمّعةً حسب category مع إضافة WITH ROLLUP.

  2. اكتب استعلام SELECT على جدول orders يعرض payment_method و GROUPING(payment_method) باسم is_total و SUM(total_usd) باسم revenue مجمّعةً حسب payment_method WITH ROLLUP.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

8أسئلة 1أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي8 أسئلة تنتظرك
01

ماذا يضيف إلحاق العبارة WITH ROLLUP بجملة GROUP BY dept_id إلى نتائج الاستعلام؟

يولّد WITH ROLLUP صفاً إضافياً للمجموع العام ويضع القيمة NULL في عمود التجميع للدلالة على الشمول الكلي.

02

عند كتابة GROUP BY region, country WITH ROLLUP، ما مستويات التلخيص التي يولّدها المحرك؟

يُجمّع WITH ROLLUP الأعمدة من اليمين إلى اليسار؛ فيُصفّر العمود الأيمن country أولاً ثم العمودين معاً.

03

ماذا تُعيد الدالة GROUPING(dept_id) في صف المجموع الناتج عن ROLLUP مقارنةً بالصف العادي (حتى لو كانت قيمته في الجدول NULL)؟

صُمّمت دالة GROUPING(col) لتُعيد 1 فقط عندما تكون NULL ناتجة عن التجميع الفائق ROLLUP وتُعيد 0 للبيانات العادية.

04

ما الجملة التي تُنفَّذ أولاً في الترتيب المنطقي لتنفيذ استعلام SELECT في SQL؟

رغم أن SELECT تُكتب في بداية الاستعلام، يبدأ المحرك منطقياً بتنفيذ FROM لتحديد الجدول وقراءة بياناته.

05

ما الترتيب المنطقي الصحيح لتنفيذ المراحل الأربع: WHERE و GROUP BY و HAVING و SELECT؟

تُصفّى الصفوف أولاً بـ WHERE، ثم تُجمّع بـ GROUP BY، ثم تُصفّى المجموعات بـ HAVING، ثم تُعرض الأعمدة بـ SELECT.

06

لماذا يؤدي استخدام الاسم المستعار للعمود المعرّف في SELECT داخل جملة WHERE إلى الخطأ 1054؟

تُنفّذ WHERE في المرحلة الثانية بينما لا تُعرّف الأسماء المستعارة للأعمدة إلا عند الوصول للمرحلة الخامسة SELECT.

07

لماذا يصح استخدام الاسم المستعار للجدول (مثل FROM orders AS o) داخل جملة WHERE (مثل WHERE o.total > 100)؟

تُربط الأسماء المستعارة للجداول في المرحلة الأولى FROM، لذا تتعرف عليها جميع المراحل اللاحقة ومنها WHERE.

08

أي جملة تُنفَّذ في المرحلة الأخيرة تماماً (المرحلة 8) بعد اكتمال فرز النتائج بجملة ORDER BY؟

تُنفَّذ LIMIT و OFFSET في المرحلة الثامنة والأخيرة لاقتطاع عدد الصفوف المطلوب بعد اكتمال ترتيبها.