0Pricing
SQL Interview Prep · درس

تسلسل عدة CTEs

إنشاء مسار من الخطوات المسماة التي تشير إلى بعضها بعضًا

تسلسل عدة CTEs درس مجاني في SQL Interview Prep على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.

لماذا نربط CTEs؟

نادرًا ما تتسع مسائل المقابلات الحقيقية لخطوة واحدة. يتيح لك ربط CTEs إنشاء مسار معالجة من مراحل مُسمّاة، إذ تحوّل كل مرحلة ناتج المرحلة السابقة. وهذا يحاكي طريقة تفكيك المهندس المتمرس للاستعلامات الصعبة إلى أجزاء يمكن إدارتها.

بدلًا من تداخل الاستعلامات الفرعية على ثلاثة مستويات، تكتب كل خطوة مرة واحدة، وتمنحها اسمًا، وتتيح للخطوات اللاحقة الإشارة إليها.

الصياغة المفصولة بفواصل

لتعريف عدة CTEs، تكتب WITH مرة واحدة، ثم تفصل بين كل كتلة مُسمّاة بفاصلة. لا تكرّر الكلمة المفتاحية WITH.

  • توجد WITH واحدة في البداية.
  • توجد فاصلة بين كل تعريفين لـ CTE.
  • لا توجد فاصلة قبل الاستعلام الرئيسي النهائي.
WITH a AS (
    SELECT customer_id FROM orders
),
b AS (
    SELECT customer_id FROM a
)
SELECT *
FROM b;

يمكن لـ CTEs اللاحقة الإشارة إلى السابقة

تكمن قوة الربط في أن CTE يمكنها قراءة أي CTE عُرّفت قبلها. وتتيح هذه الرؤية باتجاه واحد إنشاء سلسلة من التبعيات.

لا يمكن لـ CTE سابقة رؤية CTE لاحقة، لذلك يهم الترتيب. رتّب مراحلَك بدءًا من البيانات الخام وصولًا إلى الشكل النهائي.

WITH filtered AS (
    SELECT *
    FROM events
    WHERE event_type = 'purchase'
),
per_user AS (
    SELECT user_id, COUNT(*) AS purchases
    FROM filtered
    GROUP BY user_id
)
SELECT *
FROM per_user;

مثال تطبيقي: مسار معالجة من ثلاث مراحل

السؤال: بين العملاء الذين أنفقوا أكثر من 1000 دولار، ما متوسط الإنفاق؟ قسّم المسألة إلى ثلاث مراحل: احسب إجمالي الإنفاق لكل عميل، ثم صفِّ كبار المنفقين، ثم احسب متوسط إنفاقهم.

يوثّق اسم كل CTE الغرض منه، لذلك يفهم المراجع مسار التنفيذ فورًا.

WITH spend AS (
    SELECT customer_id, SUM(amount) AS total
    FROM orders
    GROUP BY customer_id
),
big_spenders AS (
    SELECT customer_id, total
    FROM spend
    WHERE total > 1000
)
SELECT AVG(total) AS avg_big_spend
FROM big_spenders;

يهم ترتيب التعريفات

بما أن الرؤية تكون باتجاه واحد، يجب إدراج CTE التي تعتمد على أخرى بعد التبعية التي تعتمد عليها. إذا أشرت إلى اسم لم يُعرّف بعد، فستصدر قاعدة البيانات خطأ "العلاقة غير موجودة".

من العادات الجيدة: اقرأ قائمة CTEs من الأعلى إلى الأسفل، وتحقق من أن كل اسم مستخدم قد ظهر مسبقًا فوقه.

الإشارة إلى CTE واحدة من عدة CTEs أخرى

يمكن لـ CTE واحدة تزويد عدة CTEs لاحقة بالبيانات. وهنا يتفوّق الربط على الاستعلامات الفرعية المتداخلة: تحسب النتيجة الأساسية مرة واحدة، ثم تتفرّع منها.

في هذه الحالة، تقرأ كل من active وrecent من base، مما يتجنب تكرار المنطق.

WITH base AS (
    SELECT * FROM users WHERE deleted = false
),
active AS (
    SELECT id FROM base WHERE last_login > NOW() - INTERVAL '7 days'
),
recent AS (
    SELECT id FROM base WHERE created_at > NOW() - INTERVAL '30 days'
)
SELECT (SELECT COUNT(*) FROM active) AS active_cnt,
       (SELECT COUNT(*) FROM recent) AS recent_cnt;

ضم CTEين معًا

كثيرًا ما تُضم CTEs المترابطة في الاستعلام الرئيسي. احسب كل جانب على حدة، ثم ادمجهما. يحافظ ذلك على عزل كل عملية حسابية ويجعل عملية الضم بسيطة.

نحسب أدناه عدد الطلبات وعدد عمليات استرداد الأموال بشكل مستقل، ثم نضمهما لكل عميل.

WITH orders_cte AS (
    SELECT customer_id, COUNT(*) AS orders
    FROM orders GROUP BY customer_id
),
refunds_cte AS (
    SELECT customer_id, COUNT(*) AS refunds
    FROM refunds GROUP BY customer_id
)
SELECT o.customer_id, o.orders, COALESCE(r.refunds, 0) AS refunds
FROM orders_cte o
LEFT JOIN refunds_cte r ON r.customer_id = o.customer_id;

قابلية القراءة بدلًا من التداخل

قارن بين استعلام فرعي متداخل على ثلاثة مستويات ومسار معالجة مكوّن من ثلاث CTEs. يجبر الإصدار المتداخل القارئ على فك التداخل ذهنيًا من الداخل إلى الخارج. أما إصدار CTE فيُقرأ بترتيب التنفيذ، من الأعلى إلى الأسفل.

يقدّر القائمون على المقابلات نهج CTE لأنه النهج الذي يرغبون في صيانته ضمن بيئة الإنتاج. فتسمية كل مرحلة توثيق لا يتقادم أبدًا.

خطأ شائع عند ربط CTEs

غالبًا ما يضيف المبتدئون فاصلة بعد آخر CTE، مباشرةً قبل SELECT الرئيسي. وتُعد هذه الفاصلة الزائدة خطأً في الصياغة.

  • توضع الفواصل بين تعريفات CTE فقط.
  • يتبع قوس الإغلاق النهائي الاستعلام الرئيسي مباشرةً، من دون فاصلة.

وهناك مأزق آخر: نسيان أن كل CTE تحتاج إلى SELECT كامل خاص بها داخل القوسين.

هل تُنفَّذ كل مرحلة على حدة؟

هذه نقطة دقيقة في المقابلات: يُقرأ مسار المعالجة منطقيًا كخطوات منفصلة، لكن قد يدمج المُحسِّن هذه الخطوات في خطة تنفيذ واحدة. وفي معظم المحركات، لا تُجبر على دفع تكلفة إنشاء نتائج وسيطة فعليًا.

لذلك يساعدك الربط على فهم الاستعلام دون أن يكلّف الأداء بالضرورة. اذكر هذه النقطة لإظهار عمق فهمك.

تسمية المراحل مثل مسار المعالجة

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

  • تُعد spend وbig_spenders أفضل من step1 وstep2.
  • ينبغي أن يتمكن القارئ من استنتاج المسار كاملًا من أسماء CTEs وحدها.
  • يجعل اتساق التسمية بين المراحل عملية الضم في الاستعلام الرئيسي واضحة.

في المقابلة، تشير تسمية المراحل بوضوح إلى أنك تكتب SQL قابلة للصيانة في بيئة الإنتاج.

تحقق سريع

تحقق من مدى فهمك لكيفية إشارة CTEs المترابطة بعضها إلى بعض.

مراجعة: ربط CTEs

تعلّمت إنشاء مسارات معالجة: WITH واحدة، وتعريفات CTE مفصولة بفواصل، ورؤية باتجاه واحد، بحيث يمكن لكل مرحلة قراءة المراحل السابقة.

  • رتّب CTEs بدءًا من البيانات الخام وصولًا إلى النتيجة النهائية.
  • أعد استخدام CTE أساسية في عدة خطوات لاحقة.
  • لا تضع فاصلة زائدة قبل الاستعلام الرئيسي.
  • يساعد الربط على قابلية القراءة من دون أن يضر الأداء بالضرورة.

التالي: مقارنة CTEs بالاستعلامات الفرعية والجداول المؤقتة.

الأسئلة الشائعة

هل درس «تسلسل عدة CTEs» مجاني؟

نعم — نص درس «تسلسل عدة CTEs» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.

ماذا ستتعلم في «تسلسل عدة CTEs»؟

إنشاء مسار من الخطوات المسماة التي تشير إلى بعضها بعضًا تتمرن على SQL Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ SQL Interview Prep؟

لا تُشترط خبرة سابقة. SQL Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «تسلسل عدة CTEs»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس SQL Interview Prep هذا؟

نعم. كل درس في SQL Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. كتابة أول CTE لك
  2. تسلسل عدة CTEs
  3. CTE مقابل الاستعلام الفرعي مقابل الجدول المؤقت
  4. إعادة هيكلة الاستعلامات المتداخلة إلى CTEs
← العودة إلى SQL Interview Prep