الأعضاء الأساسيون والتكراريون
البنية ذات الجزأين لـ CTE تكراري وكيفية عمل الإنهاء
الأعضاء الأساسيون والتكراريون درس مجاني في SQL Interview Prep على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.
لماذا تُطرح أسئلة عن CTEs التكرارية
عندما يقدّم لك المُحاوِر مخططًا تنظيميًا أو قائمة مواد أو شجرة فئات ويطلب منك إظهار كل العناصر التابعة، فهو يختبر ما إذا كنت ستلجأ إلى CTE تكرارية. لا تستطيع عمليات الربط العادية اجتياز عدد ثابت من المستويات إلا، بينما تستطيع التكرارية اجتياز عمق اعتباطي.
العبارة الكاشفة في السؤال هي "إلى أي عمق" أو "حتى النهاية". تلك هي الإشارة التي تنتظرها. في هذا الدرس ستتعلّم البنية ذات الجزأين التي تشترك فيها كل CTE تكرارية: جزء البداية والعضو التكراري.
الهيكل الأساسي ذو الجزأين
تحتوي CTE التكرارية دائمًا على الكلمة المفتاحية WITH RECURSIVE (في Postgres وSQLite وMySQL 8+؛ أما SQL Server فيحذف RECURSIVE)، وعلى بنية تتكون من استعلامين مدموجين باستخدام UNION ALL:
- جزء البداية — الصفوف الأولية، ويُنفَّذ مرة واحدة.
- العضو التكراري — يشير إلى اسم CTE نفسها، ويُنفَّذ بشكل متكرر.
احفظ هذا الهيكل؛ فالمُحاوِرون يحبون أن يطلبوا منك كتابته من الصفر.
WITH RECURSIVE cte AS (
-- anchor member
SELECT ...
UNION ALL
-- recursive member
SELECT ... FROM cte JOIN ...
)
SELECT * FROM cte;ما الذي يفعله جزء البداية
جزء البداية هو استعلام عادي لا يحتوي على مرجع إلى CTE. وهو ينتج الصفوف الأولية — أي نقطة البداية عند المستوى صفر. في المخطط التنظيمي يكون عادةً الرئيس التنفيذي (الصف الذي تكون فيه خانة المدير NULL)؛ أما في سلسلة أعداد فهو العدد الأول.
يُنفَّذ جزء البداية مرة واحدة بالضبط. ويصبح ناتجه الدفعة الأولى من الصفوف التي تُمرَّر إلى الخطوة التكرارية.
-- Anchor: the top of the hierarchy
SELECT id, name, manager_id, 1 AS depth
FROM employees
WHERE manager_id IS NULLما الذي يفعله العضو التكراري
يشير العضو التكراري إلى CTE باسمها. وفي كل تكرار، يربط الصفوف التي أنتجها التكرار السابق بالجدول الأساسي للعثور على المستوى التالي.
وهو لا يرى محتوى CTE كاملًا حتى تلك اللحظة — بل يرى الصفوف التي أُضيفت في الخطوة السابقة مباشرةً فقط. هذا هو النموذج الذهني الأساسي الذي يستكشفه المُحاوِرون.
-- Recursive: children of the rows found so far
SELECT e.id, e.name, e.manager_id, c.depth + 1
FROM employees e
JOIN cte c ON e.manager_id = c.idتجميع الأجزاء
ادمج جزءَ البداية والعضوَ التكراري باستخدام UNION ALL، وسيتولى المحرك التكرار تلقائيًا. تضيف كل دورة المستوى التالي إلى النتائج حتى يعيد العضو التكراري صفر صفوف، وعندها يتوقف التكرار.
إليك استعلامًا كاملًا قابلًا للتنفيذ لاجتياز مخطط تنظيمي، ويتتبع أيضًا depth.
WITH RECURSIVE org AS (
SELECT id, name, manager_id, 1 AS depth
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id, o.depth + 1
FROM employees e
JOIN org o ON e.manager_id = o.id
)
SELECT id, name, depth FROM org ORDER BY depth, id;كيفية عمل التوقف
يتوقف التكرار عندما ينتج العضو التكراري صفوفًا جديدة لا، بل لا ينتج أي صفوف جديدة. ولا تحتاج إلى عدّاد حلقات صريح — إذ ينفد الربط تلقائيًا عند الوصول إلى أوراق الشجرة.
في المثال التنظيمي، عندما تصل إلى موظفين ليس لديهم مرؤوسون مباشِرون، لا يعثر الربط في التكرار التالي على أبناء، فيعيد نتيجة فارغة ويتوقف المحرك. وفهم هذا السلوك الذي ينهي نفسه بنفسه سؤال متابعة كلاسيكي.
UNION ALL مقابل UNION
يسأل المُحاوِرون غالبًا عن سبب استخدامنا UNION ALL بدلًا من UNION. هناك سببان:
- الأداء — تزيل
UNIONالتكرارات في كل تكرار، وهذا مكلف. - الصحة — لا يمكن أن تحدث الصفوف المكررة عادةً في الشجرة، لذا فإن إزالة التكرارات جهد ضائع.
استخدم UNION فقط عندما تكون البنية رسمًا بيانيًا وتريد عمدًا دمج العقد المتكررة — لكن من أجل الأمان من الحلقات، تكون الحواجز الصريحة أفضل (وسنتناولها لاحقًا).
تتبع العمق والمسار
يجعل عمودان إضافيان النتائج التكرارية أكثر فائدة بكثير، وكثيرًا ما يُطلبان في المقابلات:
- depth — ابدأ بالقيمة 1 في جزء البداية، وأضف 1 في العضو التكراري.
- path — اجمع سلسلة المعرّفات أو الأسماء حتى تتمكن من رؤية المسار من الجذر إلى العقدة.
كما أن بناء path كسلسلة نصية يجعله أداة لاكتشاف الحلقات لاحقًا.
WITH RECURSIVE org AS (
SELECT id, name, manager_id, 1 AS depth,
CAST(name AS VARCHAR(1000)) AS path
FROM employees WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id, o.depth + 1,
o.path || ' > ' || e.name
FROM employees e JOIN org o ON e.manager_id = o.id
)
SELECT name, depth, path FROM org;يجب أن تتطابق أنواع الأعمدة
هناك مشكلة دقيقة يجب الانتباه إليها: يجب أن يعيد جزء البداية والعضو التكراري العدد نفسه من الأعمدة وبـأنواع متوافقة. إذا أنشأت سلسلة path، فيجب تحويل القيمة الأولية في جزء البداية إلى نوع ذي حجم كافٍ (مثل VARCHAR(1000))، وإلا فقد يقتطع المحرك القيمة أو يطرح خطأ عدم تطابق في النوع خلال التكرارات اللاحقة.
هذا بالضبط نوع التفاصيل التي يضعها المُحاوِر ليرى ما إذا كنت قد شغّلت CTE تكرارية فعلًا، لا أن قرأت عنها فحسب.
مثال على قائمة المواد
يحل الهيكل نفسه مشكلة قائمة المواد: given a part، اعرض كل الأجزاء الفرعية على أي عمق. يحدد جزء البداية التجميعة العليا، بينما يتتبع العضو التكراري روابط parent_part إلى child_part.
لاحظ أن البنية مطابقة للمخطط التنظيمي — الذي يتغير هو أسماء الأعمدة فقط. وإدراك أن هيكلًا واحدًا يناسب مشكلات عديدة هو مهارة المقابلة الحقيقية.
WITH RECURSIVE bom AS (
SELECT child_part, parent_part, 1 AS lvl
FROM parts WHERE parent_part = 'ENGINE'
UNION ALL
SELECT p.child_part, p.parent_part, b.lvl + 1
FROM parts p JOIN bom b ON p.parent_part = b.child_part
)
SELECT child_part, lvl FROM bom;ملاحظات حول اللهجات
ورقة غش سريعة للتوافق بين اللهجات، يقدّرها المُحاوِرون:
- PostgreSQL وSQLite وMySQL 8+:
WITH RECURSIVE name AS (...). - SQL Server: استخدم فقط
WITH name AS (...)— فكلمةRECURSIVEضمنية، كما أنه يفرض قيمة افتراضية لـMAXRECURSIONمقدارها 100. - Oracle: يدعم CTEs التكرارية وكذلك الصياغة الأقدم
CONNECT BY.
إن قولك إن "SQL Server لا يستخدم الكلمة RECURSIVE" يُظهر اتساعًا حقيقيًا في معرفتك.
تحقق سريع
اختبر مدى استيعابك للبنية ذات الجزأين.
مراجعة
أصبحت الآن متمكنًا من الهيكل الأساسي لـ CTE التكرارية:
- WITH RECURSIVE + جزء البداية +
UNION ALL+ العضو التكراري. - يهيّئ جزء البداية المستوى صفر ويُنفَّذ مرة واحدة.
- يربط العضو التكراري التكرار السابق بالجدول الأساسي، ويستمر حتى لا يعيد أي صفوف.
- استخدم
UNION ALL، وتتبعdepthوpath، وحافظ على توافق أنواع الأعمدة.
التالي: تطبيق هذا الهيكل لاجتياز مخطط تنظيمي حقيقي صعودًا وهبوطًا.
الأسئلة الشائعة
هل درس «الأعضاء الأساسيون والتكراريون» مجاني؟
نعم — نص درس «الأعضاء الأساسيون والتكراريون» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.
ماذا ستتعلم في «الأعضاء الأساسيون والتكراريون»؟
البنية ذات الجزأين لـ CTE تكراري وكيفية عمل الإنهاء تتمرن على SQL Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ SQL Interview Prep؟
لا تُشترط خبرة سابقة. SQL Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «الأعضاء الأساسيون والتكراريون»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس SQL Interview Prep هذا؟
نعم. كل درس في SQL Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الأعضاء الأساسيون والتكراريون
- التنقل في المخطط التنظيمي
- إنشاء سلاسل الأرقام والتواريخ
- تجنب التكرار اللانهائي