الانتقال إلى المحتوى الرئيسي
يدعم ClickHouse التعبيرات الجدولية الشائعة (CTE)، والتعبيرات القياسية الشائعة، والاستعلامات التكرارية.

التعبيرات الجدولية الشائعة

تمثل التعبيرات الجدولية الشائعة استعلامات فرعية مُسمّاة. ويمكن الإشارة إليها بالاسم في أي موضع داخل استعلام SELECT يُسمح فيه باستخدام تعبير جدولي. كما يمكن الإشارة إلى الاستعلامات الفرعية المُسمّاة بالاسم ضمن نطاق الاستعلام الحالي أو ضمن نطاقات الاستعلامات الفرعية التابعة. يُستبدل كل مرجع إلى تعبير جدولي شائع في استعلامات SELECT دائمًا بالاستعلام الفرعي الوارد في تعريفه إذا لم يكن CTE معرّفًا صراحةً على أنه materialized (راجع التعبيرات الجدولية الشائعة المُجسَّدة). ويُمنَع التكرار العودي بإخفاء CTE الحالي من عملية حلّ المعرّفات. يرجى ملاحظة أن CTEs لا تضمن النتائج نفسها في جميع المواضع التي يُشار إليها فيها، لأن الاستعلام يُعاد تنفيذه عند كل استخدام.

الصيغة

مثال

فيما يلي مثال على حالة يُعاد فيها تنفيذ استعلام فرعي:
إذا كانت CTEs تمرّر النتائج نفسها تمامًا، لا مجرد جزء من الشيفرة، فسترى دائمًا 1000000 لكن بما أننا نشير إلى cte_numbers مرتين، تُولَّد أرقام عشوائية في كل مرة، ولذلك نرى نتائج عشوائية مختلفة مثل 280501, 392454, 261636, 196227 وهكذا…

التعبيرات الجدولية الشائعة المُجسَّدة

بشكل افتراضي، يضمّن ClickHouse الاستعلام الفرعي الخاص بـ CTE في كل موضع يُشار إليه فيه، ويعيد تنفيذه في كل مرة. تؤدي إضافة الكلمة المفتاحية MATERIALIZED إلى توجيه ClickHouse لتنفيذ الاستعلام الفرعي لـ CTE مرة واحدة فقط، وتخزين النتائج في جدول مؤقت، ثم خدمة جميع المراجع من ذلك الجدول. ويكون هذا مفيدًا بشكل خاص عندما يُشار إلى CTE نفسه عدة مرات داخل الاستعلام (على سبيل المثال، في عمليات self-join أو في عدة استعلامات فرعية IN)، لأن العملية الحسابية الأساسية لا تحدث إلا مرة واحدة.
تُعد Materialized CTEs ميزة تجريبية. ويتطلب استخدامها تفعيل المحلّل والإعداد enable_materialized_cte.

الصيغة

متى تستخدم

تكون Materialized CTEs أكثر فائدة في الحالات التالية:
  • عند الإشارة إلى CTE نفسه أكثر من مرة ضمن استعلام. فبدون MATERIALIZED، تُعيد كل إشارة تنفيذ الاستعلام الفرعي بشكل مستقل.
  • عندما يحتوي CTE على دوال غير حتمية مثل generateRandom. يضمن materializing أن ترى جميع الإشارات البيانات نفسها.
  • عندما يتضمن CTE حسابات مكلفة (مثل عمليات aggregation وJOIN وعمليات المسح الكبيرة) ولا ينبغي تكرارها.
إذا تمت الإشارة إلى materialized CTE مرة واحدة فقط، فإن ClickHouse يضمّنه تلقائيًا داخل استعلام فرعي عادي لتجنّب overhead غير الضروري.

أمثلة

المثال 1: ربط ذاتي على CTE مُجسَّدة من دون MATERIALIZED، سينفّذ كل جانب من جانبي الربط الاستعلام الفرعي بشكل مستقل. مع MATERIALIZED، لا يُمسَح الجدول إلا مرة واحدة، ويقرأ جانبا الربط من الجدول المؤقت نفسه.
مثال 2: نتائج حتمية مع دوال غير حتمية تنتج تعبيرات الجدول الشائعة العادية (CTEs) مع generateRandom نتائج مختلفة في كل موضع تتم فيه الإشارة إليها. يضمن تجسيد الـ CTE الاتساق:
لأن كلا المرجعين يقرآن من البيانات المجسّدة نفسها، تكون النتيجة دائمًا 1000000. مثال 3: ربط تعابير CTE المجسّدة يمكن لتعابير CTE المجسّدة أن تُشير إلى تعابير CTE مجسّدة أخرى. يحلّ ClickHouse التبعيات ويُجسّدها بالترتيب الصحيح:
لا يهم ترتيب تعريفات CTE — ويُسمح بالإشارة إلى تعريفات تَرِد لاحقًا:

القيود

  • يتطلب إعدادًا تجريبيًا: يجب تمكين الإعداد enable_materialized_cte.
  • المحلِّل مطلوب: لا تعمل عبارات CTE المُجسَّدة إلا عند تمكين المحلِّل (enable_analyzer = 1).
  • غير مدعوم مع RECURSIVE: لا يُسمح بالجمع بين الكلمتين المفتاحيتين MATERIALIZED وRECURSIVE، وينتج عن ذلك استثناء UNSUPPORTED_METHOD.
  • عبارات CTE المرتبطة غير مسموح بها: لا يمكن لعبارة CTE مُجسَّدة أن تُشير إلى أعمدة من نطاقات الاستعلام الخارجية.

التعبيرات القياسية الشائعة

يتيح لك ClickHouse تعريف أسماء مستعارة لأي تعبيرات قياسية في عبارة WITH. ويمكن الرجوع إلى التعبيرات القياسية الشائعة في أي موضع ضمن الاستعلام.
إذا كان التعبير القياسي المشترك يشير إلى شيء غير قيمة حرفية ثابتة، فقد يؤدي ذلك إلى وجود متغيرات حرة. يحلّ ClickHouse أي معرّف ضمن أقرب نطاق ممكن، ما يعني أن المتغيرات الحرة قد تشير إلى كيانات غير متوقعة في حال تعارض الأسماء، أو قد تؤدي إلى استعلام فرعي مترابط. يوصى بتعريف CSE على شكل دالة لامبدا (وذلك ممكن فقط عند تمكين المحلّل)، مع ربط جميع المعرّفات المستخدمة، لتحقيق سلوك أكثر قابلية للتنبؤ عند حلّ معرّفات التعبير.

الصيغة

أمثلة

مثال 1: استخدام تعبير ثابت كـ”متغير”
مثال 2: استخدام الدوال عالية الرتبة لتقييد المعرّفات
مثال 3: استخدام الدوال عالية الترتيب مع المتغيرات الحرة تُظهر أمثلة الاستعلامات التالية أن المعرّفات غير المقيّدة تُفسَّر على أنها كيان ضمن أقرب نطاق. هنا، لا يكون extension مقيّدًا داخل متن دالة لامبدا gen_name. مع أن extension مُعرَّف على أنه '.txt' كتعبير قياسي شائع ضمن نطاق تعريف generated_names واستخدامه، فإنه يُفسَّر على أنه عمود في الجدول extension_list، لأنه متاح في الاستعلام الفرعي generated_names.
مثال 4: استبعاد نتيجة التعبير sum(bytes) من قائمة أعمدة جملة SELECT
مثال 5: استخدام نتائج استعلام فرعي يُرجِع قيمة واحدة
مثال 6: إعادة استخدام تعبير داخل استعلام فرعي

الاستعلامات التكرارية

يسمح المُعدِّل الاختياري RECURSIVE لاستعلام WITH بالإشارة إلى ناتجه الخاص. مثال: مثال: جمع الأعداد الصحيحة من 1 إلى 100
تعتمد تعبيرات CTE التكرارية على محلل الاستعلام الذي طُرح في الإصدار 24.3. إذا كنت تستخدم الإصدار 24.3+ وواجهت الاستثناء (UNKNOWN_TABLE) أو (UNSUPPORTED_METHOD)، فهذا يشير إلى أن المحلل معطّل على المثيل أو الدور أو ملف التعريف لديك. لتفعيل المحلل، فعِّل الإعداد allow_experimental_analyzer أو حدِّث إعداد compatibility إلى إصدار أحدث. واعتبارًا من الإصدار 24.8، أصبح المحلل معتمدًا بالكامل للاستخدام في بيئات production، وأُعيدت تسمية الإعداد allow_experimental_analyzer إلى enable_analyzer.
تكون الصيغة العامة لاستعلام WITH التكراري دائمًا على النحو التالي: عبارة غير تكرارية، ثم UNION ALL، ثم عبارة تكرارية، ولا يجوز إلا للعبارة التكرارية أن تتضمن مرجعًا إلى مخرجات الاستعلام نفسه. ويُنفَّذ استعلام CTE التكراري كما يلي:
  1. قيِّم العبارة غير التكرارية. وضع نتيجة استعلام العبارة غير التكرارية في جدول عمل مؤقت.
  2. ما دام جدول العمل غير فارغ، كرِّر الخطوات التالية:
    1. قيِّم العبارة التكرارية، مع استبدال المرجع الذاتي التكراري بالمحتويات الحالية لجدول العمل. وضع نتيجة استعلام العبارة التكرارية في جدول وسيط مؤقت.
    2. استبدل محتويات جدول العمل بمحتويات الجدول الوسيط، ثم أفرغ الجدول الوسيط.
تُستخدم الاستعلامات التكرارية عادةً للتعامل مع البيانات الهرمية أو البيانات ذات البنية الشجرية. على سبيل المثال، يمكننا كتابة استعلام ينفِّذ اجتيازًا للشجرة: مثال: اجتياز الشجرة لننشئ أولًا جدول الشجرة:
يمكننا اجتياز تلك الشجرة باستخدام الاستعلام التالي: مثال: اجتياز الشجرة

ترتيب البحث

لإنشاء ترتيب العمق أولًا، نحسب لكل صف في النتيجة مصفوفةً من الصفوف التي سبق أن زرناها: مثال: اجتياز الشجرة بترتيب العمق أولًا
لإنشاء ترتيب بالعرض أولًا، تتمثل الطريقة القياسية في إضافة عمود يتتبّع عمق البحث: مثال: ترتيب اجتياز الشجرة بالعرض أولًا

اكتشاف الحلقات

لننشئ أولًا جدول graph:
يمكننا اجتياز هذا الرسم البياني باستخدام الاستعلام التالي: مثال: اجتياز الرسم البياني دون اكتشاف الدورات
ولكن إذا أضفنا حلقة إلى ذلك المخطط، فسيفشل الاستعلام السابق مع ظهور الخطأ Maximum recursive CTE evaluation depth:
الطريقة القياسية للتعامل مع الدورات هي حساب مصفوفة من العُقد التي تمت زيارتها بالفعل: مثال: اجتياز الرسم البياني مع اكتشاف الدورات

استعلامات لا نهائية

يمكن أيضًا استخدام استعلامات CTE التكرارية اللانهائية إذا استُخدم LIMIT في الاستعلام الخارجي: مثال: استعلام CTE تكراري لا نهائي

الفاصلة الختامية

يُسمح بوضع فاصلة بعد آخر عنصر في جملة WITH:
آخر تعديل في ٢ يوليو ٢٠٢٦