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

التعبيرات الجدولية الشائعة WITH والاستعلامات العودية في MySQLMySQL Common Table Expressions WITH and Recursive CTEs

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

قدّم إصدار MySQL 8.0 ميزة التعبيرات الجدولية الشائعة (CTEs)، وهي مجموعات نتائج مؤقتة مسماة تُعرَّف في مطلع الاستعلام باستخدام الصيغة WITH cte_name AS (SELECT ...):

  • القراءة المتسلسلة من الأعلى للأسفل: بدلاً من دفن الجداول المشتقة داخل أقواس متداخلة معقدة في جملة FROM، تتيح لك تعبيرات WITH تنظيم منطق الاستعلام خطوة بخطوة من الأعلى إلى الأسفل.
  • نطاق عمر مؤقت للاستعلام فقط: يعيش التعبير الجدولي المؤقت طوال فترة تنفيذ التعليمة الوحيدة التي تليه مباشرةً (SELECT أو INSERT أو UPDATE أو DELETE) ثم يزول تلقائياً.
مخطط التعبيرات الجدولية الشائعة WITH والاستعلامات العودية WITH RECURSIVE في MySQL 8
SQL
-- Define a named CTE for customer paid totals, then join with users
WITH customer_paid_totals AS (
  SELECT user_id, COUNT(*) AS orders_cnt,
         SUM(total_amount) AS total_spent
  FROM orders WHERE status = 'paid'
  GROUP BY user_id
)
SELECT u.full_name, cpt.orders_cnt, cpt.total_spent
FROM customer_paid_totals AS cpt
INNER JOIN users AS u ON cpt.user_id = u.user_id
WHERE cpt.total_spent >= 500.00;

عند بناء تقارير تحليلية متعددة المراحل، يمكنك تسلسل عدة تعبيرات جدولية داخل جملة WITH واحدة عبر الفصل بين كل تعبير والذي يليه بفاصلة عادية:

  • كتابة كلمة WITH مرة واحدة فقط: تُكتب كلمة WITH مرة واحدة في بداية الاستعلام على النحو WITH step_one AS (...), step_two AS (...) SELECT ... دون تكرار كلمة WITH بعد الفاصلة.
  • البناء التراكمي للخطوات: يستطيع كل تعبير جدولي لاحق أن يستعلم من أي تعبير سبق تعريفه في الأعلى، مما يحوّل الاستعلام المعقد إلى خط أنابيب واضح ومرتب.
SQL
-- Chain two CTEs: first aggregate item revenue, then filter VIPs
WITH order_revenue AS (
  SELECT order_id, SUM(quantity * unit_price) AS net_val
  FROM order_items GROUP BY order_id
),
customer_ltv AS (
  SELECT o.user_id, SUM(orv.net_val) AS ltv
  FROM orders AS o
  INNER JOIN order_revenue AS orv ON o.order_id = orv.order_id
  GROUP BY o.user_id
)
SELECT user_id, ltv FROM customer_ltv WHERE ltv > 1000;

من أبرز المزايا الهندسية للتعبير الجدولي CTE مقارنةً بالجدول المشتق التقليدي داخل FROM هي إمكانية إعادة استخدامه عدة مرات داخل الاستعلام الواحد:

  • تعريف واحد واستدعاءات متعددة: بينما يضطرك الجدول المشتق لنسخ الكود وتكراره إذا احتجته مرتين، يمكنك تعريف CTE مرة واحدة في الأعلى ثم الإشارة إليه مرتين أو أكثر بالاسم في الاستعلام الرئيسي.
  • التخزين المؤقت لمرة واحدة: عندما يُستدعى التعبير الجدولي عدة مرات في نفس الاستعلام، يحسب MySQL 8 نتيجته مرة واحدة فقط في جدول داخلي مؤقت ويعيد قراءتها بكفاءة.
SQL
-- Define department payroll once and compare each dept to the overall avg
WITH dept_payroll AS (
  SELECT department_id, SUM(salary) AS total_payroll
  FROM employees
  GROUP BY department_id
)
SELECT d1.department_id, d1.total_payroll
FROM dept_payroll AS d1
WHERE d1.total_payroll > (
  SELECT AVG(d2.total_payroll) FROM dept_payroll AS d2
);

عندما يشير التعبير الجدولي إلى اسمه الذاتي داخل تعريفه لتوليد بيانات تكرارية، يجب إضافة الكلمة المفتاحية RECURSIVE لتصبح الصيغة WITH RECURSIVE cte_name AS (...). ويتكون كل استعلام عودي من جزأين يربطهما UNION ALL:

  • 1. جملة الأساس (Anchor Member): استعلام SELECT غير عودي يُنفذ مرة واحدة في البداية لتحديد نقطة الانطلاق (الصف الجذر).
  • 2. الجملة العودية (Recursive Member): استعلام SELECT يستدعي اسم cte_name نفسه لتوليد الدفعة التالية من الصفوف، ويتكرر حتى ترجع الدورة صفراً من الصفوف الجديدة (شرط التوقف).
SQL
-- Generate an integer sequence from 1 to 5 using WITH RECURSIVE
WITH RECURSIVE number_series AS (
  SELECT 1 AS seq_num
  UNION ALL
  SELECT seq_num + 1
  FROM number_series
  WHERE seq_num < 5
)
SELECT seq_num FROM number_series;

في تطبيقات الإنتاج الفعلية، يحل WITH RECURSIVE مشكلتين شهيرتين كانتا تتطلبان حلقات برمجية معقدة في لغة التطبيق أو جداول مساعدة:

  • استعراض الأشجار الهرمية: تتبّع الهياكل الإدارية (manager_id) أو شجرة التصنيفات المتداخلة (parent_id) من الجذر حتى أعمق مستوى مع حساب رقم المستوى depth_level.
  • توليد السلاسل الزمنية المتصلة: إنشاء سلسلة تواريخ يومية متكاملة لربطها عبر LEFT JOIN بجدول المبيعات بحيث تظهر الأيام الخالية من المبيعات بقيمة صفر بدلاً من اختفائها.
SQL
-- Traverse an employee organization hierarchy from CEO down
WITH RECURSIVE org_chart AS (
  SELECT emp_id, emp_name, manager_id, 1 AS tree_level
  FROM employees WHERE manager_id IS NULL
  UNION ALL
  SELECT e.emp_id, e.emp_name, e.manager_id, oc.tree_level + 1
  FROM employees AS e
  INNER JOIN org_chart AS oc ON e.manager_id = oc.emp_id
)
SELECT emp_id, emp_name, manager_id, tree_level
FROM org_chart ORDER BY tree_level, emp_id;

يقارن الجدول التالي بين التعبيرات الجدولية القياسية والعودية والجداول المشتقة في MySQL 8:

البنيةموضع الصياغةقابل لإعادة الاستخدام بالاستعلام؟يدعم الاستدعاء العودي؟
تعبير WITH القياسيأعلى الاستعلام: WITH name AS (...)نعم (يُستدعى عدة مرات بالاسم)لا
تعبيرات متسلسلةWITH c1 AS (...), c2 AS (...)نعم (ويمكن لـ c2 القراءة من c1)لا إلا مع RECURSIVE
تعبير عودي RECURSIVEWITH RECURSIVE name AS (...)نعمنعم (للأشجار والسلاسل)
الجدول المشتقداخل جملة FROM (SELECT ...) AS aliasلا (يتطلب تكرار الكود عند الحاجة)لا

ملخص الدرس: بسّطنا في هذا الدرس الاستعلامات المعقدة باستخدام تعبيرات WITH، وسلسلنا عدة تعبيرات متتابعة، وأعدنا استخدام التعبير الواحد عدة مرات، وبنينا استعلامات عودية عبر WITH RECURSIVE لتوليد السلاسل واستعراض الهياكل الشجرية.
الخطوة التالية والدرس القادم: في الدرس القادم نختتم وحدة الاستعلامات المتقدمة بدراسة «دوال النوافذ التحليلية OVER و PARTITION BY والترتيب في MySQL».

خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

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

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

تستبدل تعبيرات WITH وWITH RECURSIVE الجداول المشتقة المتداخلة بوحدات استعلام مقروءة وقابلة لإعادة الاستخدام وقادرة على تمثيل العلاقات الهرمية. الخطوة التالية: انتقل إلى درس «دوال النوافذ التحليلية OVER و PARTITION BY والترتيب في MySQL».

مشاركة

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

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

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

المصطلحات5

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

0 / 5 مفهومةأول بطاقة، أول خطوة
01 Recursive CTEs تعبيرات WITH
تعلّم التعبيرات الجدولية الشائعة WITH والاستعلامات العودية في MySQL بأسلوب MySQL 8 الحديث مع أمثلة استعلامات SQL وتطبيقات تفاعلية.
للمراجعة
02 Readable Queries with WITH CTE تبسيط الاستعلامات بتعبير WITH
المفهوم الهندسي والصياغة العملية الخاصة بقسم تبسيط الاستعلامات بتعبير WITH في MySQL 8.
للمراجعة
03 Chaining Multiple CTE Steps تسلسل عدة تعبيرات WITH
المفهوم الهندسي والصياغة العملية الخاصة بقسم تسلسل عدة تعبيرات WITH في MySQL 8.
للمراجعة
04 Reusing CTEs Within One Query إعادة استخدام التعبير الجدولي
المفهوم الهندسي والصياغة العملية الخاصة بقسم إعادة استخدام التعبير الجدولي في MySQL 8.
للمراجعة
05 Anatomy of WITH RECURSIVE Queries تشريح الاستعلام العودي RECURSIVE
المفهوم الهندسي والصياغة العملية الخاصة بقسم تشريح الاستعلام العودي RECURSIVE في MySQL 8.
للمراجعة

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

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

الاختصارات3

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

0 / 3 مفهومةأول بطاقة، أول خطوة
01 CTE CTE
Common Table Expression
تعبير جدولي شائع يُعرّف بجملة WITH في بداية الاستعلام لتبسيط المنطق المعقد.
للمراجعة
02 Anchor Member جملة الأساس
Non-Recursive Seed Query
فرع الاستعلام الأولي غير العودي داخل WITH RECURSIVE الذي يحدد صفوف البداية.
للمراجعة
03 DAG / Tree هيكل شجري
Hierarchical Parent-Child Tree
بنية جدولية هرمية ذاتية المرجعية يتم استعراض مستوياتها عبر WITH RECURSIVE.
للمراجعة

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

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

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

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

0/2مهام منجزة
  1. نفّذ أمثلة SQL المشروحة في قسم تبسيط الاستعلامات بتعبير WITH داخل قاعدة بياناتك المحلية وتحقق من مجموعة النتائج.

  2. بدّل بين الحالات التفاعلية في قسم تسلسل عدة تعبيرات WITH وقارن كيف ينفّذ محرك MySQL 8 كل استعلام.

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

مساحة التحدي

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

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

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

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

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

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

ما هي مدة بقاء التعبير الجدولي الشائع (CTE) المعرّف بجملة WITH cte_name AS (...) في MySQL؟

تذكّر النطاق الزمني للتعبير الجدولي المؤقت.

02

عند تعريف تعبيرين جدوليّين متتاليين في بداية الاستعلام، ما هي الصياغة الصحيحة نحوياً في MySQL؟

تحقق مما إذا كانت كلمة WITH تتكرر أم يُفصل بينهما بفاصلة فقط.

03

بخلاف الجدول المشتق داخل FROM، يمكن الإشارة إلى التعبير الجدولي المعرّف في جملة WITH عدة مرات داخل الاستعلام الرئيسي دون إعادة كتابة كوده.

تذكّر ميزة إعادة استخدام CTE أكثر من مرة في نفس الاستعلام.

04

ما هما الجزآن الأساسيان اللذان يتكون منهما تعريف الاستعلام العودي WITH RECURSIVE؟

حدّد جملة نقطة البداية والجملة التكرارية اللتين يربطهما UNION ALL.

05

أي متغير نظامي في MySQL يحمي الخادم من الدوران اللانهائي إذا نسي المطور كتابة شرط التوقف داخل استعلام WITH RECURSIVE؟

تذكّر اسم متغير الحد الأقصى لعمق التكرار العودي (الافتراضي 1000).