الانتقال إلى المحتوى الرئيسي
تُستخدم استعلامات SELECT لاسترجاع البيانات. وبشكل افتراضي، تُعاد البيانات المطلوبة إلى العميل، ويمكن عند استخدامها مع INSERT INTO توجيهها إلى جدول آخر.

البنية

[WITH expr_list(subquery)]
SELECT [DISTINCT [ON (column1, column2, ...)]] expr_list
[FROM [db.]table | (subquery) | table_function] [FINAL]
[SAMPLE sample_coeff]
[ARRAY JOIN ...]
[GLOBAL] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI] JOIN (subquery)|table [(alias1 [, alias2 ...])] (ON <expr_list>)|(USING <column_list>)
[PREWHERE expr]
[WHERE expr]
[GROUP BY expr_list] [WITH ROLLUP|WITH CUBE] [WITH TOTALS]
[HAVING expr]
[WINDOW window_expr_list]
[QUALIFY expr]
[ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr] [INTERPOLATE [(expr_list)]]
[LIMIT [offset_value, ]n BY columns]
[LIMIT [n, ]m] [WITH TIES]
[SETTINGS ...]
[UNION  ...]
[INTO OUTFILE filename [TRUNCATE] [COMPRESSION type [LEVEL level]] ]
[FORMAT format]
جميع البنود اختيارية، باستثناء قائمة التعبيرات المطلوبة التي تأتي مباشرة بعد SELECT، والتي تُشرح بمزيد من التفصيل أدناه. تُشرح تفاصيل كل بند اختياري في أقسام منفصلة، وهي مُدرجة بالترتيب نفسه الذي تُنفَّذ به:

بند SELECT

تُحتسب التعبيرات المحددة في بند SELECT بعد اكتمال جميع العمليات في البنود الموضحة أعلاه. وتعمل هذه التعبيرات كما لو كانت تُطبَّق على صفوف منفصلة في النتيجة. وإذا كانت التعبيرات في بند SELECT تحتوي على دوال تجميع، فإن ClickHouse يعالج دوال التجميع والتعبيرات المستخدمة بوصفها وسيطات لها أثناء تجميع GROUP BY. إذا كنت تريد تضمين جميع الأعمدة في النتيجة، فاستخدم رمز النجمة (*). على سبيل المثال: SELECT * FROM ....

الاختيار الديناميكي للأعمدة

يتيح لك الاختيار الديناميكي للأعمدة (ويُعرف أيضًا باسم تعبير COLUMNS) مطابقة بعض الأعمدة في النتائج باستخدام تعبير نمطي re2.
COLUMNS('regexp')
على سبيل المثال، تأمل الجدول التالي:
CREATE TABLE default.col_names (aa Int8, ab Int8, bc Int8) ENGINE = TinyLog
يختار الاستعلام التالي بيانات من جميع الأعمدة التي تحتوي أسماؤها على الرمز a.
SELECT COLUMNS('a') FROM col_names
┌─aa─┬─ab─┐
│  1 │  1 │
└────┴────┘
لا تُعاد الأعمدة المحددة بترتيب أبجدي. يمكنك استخدام عدة تعبيرات COLUMNS في استعلام وتطبيق الدوال عليها. على سبيل المثال:
SELECT COLUMNS('a'), COLUMNS('c'), toTypeName(COLUMNS('c')) FROM col_names
┌─aa─┬─ab─┬─bc─┬─toTypeName(bc)─┐
│  1 │  1 │  1 │ Int8           │
└────┴────┴────┴────────────────┘
يُمرَّر كل عمود تُرجعه عبارة COLUMNS إلى الدالة على هيئة وسيط منفصل. ويمكنك أيضًا تمرير وسائط أخرى إلى الدالة إذا كانت تدعمها. توخَّ الحذر عند استخدام الدوال. إذا كانت الدالة لا تدعم عدد الوسائط التي مرَّرتها إليها، فإن ClickHouse يُلقي استثناءً. على سبيل المثال:
SELECT COLUMNS('a') + COLUMNS('c') FROM col_names
Received exception from server (version 19.14.1):
Code: 42. DB::Exception: Received from localhost:9000. DB::Exception: Number of arguments for function plus does not match: passed 3, should be 2.
في هذا المثال، تُرجِع COLUMNS('a') عمودين: aa وab. وتُرجِع COLUMNS('c') العمود bc. لا يمكن تطبيق العامل + على 3 وسيطات، لذلك يرفع ClickHouse استثناءً بالرسالة المناسبة. قد تكون أنواع بيانات الأعمدة التي طابقت التعبير COLUMNS مختلفة. وإذا لم يطابق COLUMNS أي أعمدة وكان هو التعبير الوحيد في SELECT، فإن ClickHouse يرفع استثناءً.

اختيار الأعمدة باستخدام LIKE أو ILIKE

يمكنك أيضًا اختيار الأعمدة عبر مطابقة أسمائها مع نمط بعد *، باستخدام LIKE المطابق لحالة الأحرف أو ILIKE غير المطابق لحالة الأحرف:
SELECT * ILIKE 'a%' FROM col_names
┌─aa─┬─ab─┐
│  1 │  1 │
└────┴────┘
تتبع الأنماط LIKE وILIKE دلالات LIKE، لا دلالات التعبيرات النمطية. يطابق المحرف % أي تسلسل من المحارف، ويطابق المحرف _ أي محرف واحد، ويُستخدم \ لإلغاء المعنى الخاص لكل من % و_ و\. والفرق الوحيد بينهما هو أن LIKE يطابق أسماء الأعمدة مع مراعاة حالة الأحرف، بينما ILIKE غير حساس لحالة الأحرف. على سبيل المثال:
SELECT * ILIKE 'a_' FROM col_names
يختار الاستعلام أعمدةً ذات أسماء مكوّنة من حرفين وتبدأ بـ a، مثل aa وab. تدعم * LIKE و* ILIKE أيضًا العلامات النجمية المؤهلة ومحوِّلات الأعمدة:
SELECT t.* ILIKE 'a%' EXCEPT (ab) FROM col_names AS t
┌─aa─┐
│  1 │
└────┘

النجمة

يمكنك وضع نجمة في أي جزء من الاستعلام بدلًا من تعبير. وعند تحليل الاستعلام، تُوسَّع النجمة إلى قائمة بكل أعمدة الجدول (باستثناء الأعمدة MATERIALIZED وALIAS). ولا يوجد سوى عدد قليل من الحالات التي يكون فيها استخدام النجمة مبررًا:
  • عند إنشاء dump للجدول.
  • في الجداول التي لا تحتوي إلا على عدد قليل من الأعمدة، مثل جداول النظام.
  • للحصول على معلومات عن الأعمدة الموجودة في جدول. في هذه الحالة، اضبط LIMIT 1. لكن من الأفضل استخدام الاستعلام DESC TABLE.
  • عند وجود تصفية قوية على عدد صغير من الأعمدة باستخدام PREWHERE.
  • في الاستعلامات الفرعية (لأن الأعمدة غير المطلوبة للاستعلام الخارجي تُستبعد من الاستعلامات الفرعية).
في جميع الحالات الأخرى، لا نوصي باستخدام النجمة، لأنها لا تمنحك سوى عيوب نظام إدارة قواعد البيانات العمودي بدلًا من مزاياه. وبعبارة أخرى، لا يُنصح باستخدام النجمة.

القيم القصوى

بالإضافة إلى النتائج، يمكنك أيضًا الحصول على القيم الدنيا والقصوى لأعمدة النتائج. للقيام بذلك، اضبط الإعداد extremes على 1. تُحسب القيم الدنيا والقصوى للأنواع الرقمية، والتواريخ، وقيم التاريخ والوقت. أما الأعمدة الأخرى، فتُخرَج لها القيم الافتراضية. يُحسب صفّان إضافيان — القيم الدنيا والقيم القصوى، على الترتيب. ويُخرَج هذان الصفّان الإضافيان في التنسيقات XML وJSON* وTabSeparated* وCSV* وVertical وTemplate وPretty*، بشكل منفصل عن الصفوف الأخرى. ولا يُخرَجان في التنسيقات الأخرى. في تنسيقات JSON* وXML، تُخرَج القيم القصوى في حقل منفصل باسم ‘extremes’. وفي تنسيقات TabSeparated* وCSV* وVertical، يأتي هذا الصف بعد النتيجة الرئيسية، وبعد ‘totals’ أيضًا إذا كان موجودًا. ويسبقه صف فارغ (بعد البيانات الأخرى). وفي تنسيقات Pretty*، يُخرَج الصف في جدول منفصل بعد النتيجة الرئيسية، وبعد totals أيضًا إذا كان موجودًا. وفي تنسيق Template، تُخرَج القيم القصوى وفقًا للقالب المحدد. تُحسب القيم القصوى للصفوف قبل LIMIT، ولكن بعد LIMIT BY. ومع ذلك، عند استخدام LIMIT offset, size، تُدرَج الصفوف التي تسبق offset ضمن extremes. وفي الطلبات المتدفقة، قد تتضمن النتيجة أيضًا عددًا قليلًا من الصفوف التي مرّت عبر LIMIT.

ملاحظات

يمكنك استخدام المرادفات (الأسماء المستعارة باستخدام AS) في أي جزء من الاستعلام. تدعم بنود GROUP BY وORDER BY وLIMIT BY الوسيطات الموضعية. لتمكين ذلك، فعِّل الإعداد enable_positional_arguments. بعد ذلك، على سبيل المثال، سيؤدي ORDER BY 1,2 إلى فرز صفوف الجدول حسب العمود الأول ثم العمود الثاني.

تفاصيل التنفيذ

إذا كان الاستعلام لا يتضمن بنود DISTINCT وGROUP BY وORDER BY ولا الاستعلامات الفرعية IN وJOIN، فستتم معالجة الاستعلام بالكامل على نحوٍ تدفقي، باستخدام مقدار O(1) من RAM. بخلاف ذلك، قد يستهلك الاستعلام قدرًا كبيرًا من RAM إذا لم تُحدَّد القيود المناسبة:
  • max_memory_usage
  • max_rows_to_group_by
  • max_rows_to_sort
  • max_rows_in_distinct
  • max_bytes_in_distinct
  • max_rows_in_set
  • max_bytes_in_set
  • max_rows_in_join
  • max_bytes_in_join
  • max_bytes_before_external_sort
  • max_bytes_ratio_before_external_sort
  • max_bytes_before_external_group_by
  • max_bytes_ratio_before_external_group_by
لمزيد من المعلومات، راجع قسم “الإعدادات”. يمكن استخدام الفرز الخارجي (بحفظ الجداول المؤقتة على القرص) والتجميع الخارجي.

مُعدِّلات SELECT

يمكنك استخدام المُعدِّلات التالية في استعلامات SELECT.
المُعدِّلالوصف
APPLYيتيح لك استدعاء دالة لكل صف تُعيده عبارة جدول خارجية في الاستعلام.
EXCEPTيحدِّد أسماء عمود واحد أو أكثر لاستبعادها من النتيجة. وتُحذف جميع أسماء الأعمدة المطابقة من المخرجات.
REPLACEيحدِّد اسمًا مستعارًا واحدًا أو أكثر لـ التعبيرات. يجب أن يطابق كل اسم مستعار اسم عمود من عبارة SELECT *. وفي قائمة أعمدة المخرجات، يُستبدل العمود المطابق للاسم المستعار بالتعبير الموجود في REPLACE. لا يغيِّر هذا المُعدِّل أسماء الأعمدة أو ترتيبها، لكنه قد يغيِّر القيمة ونوعها.

تركيبات المعدِّلات

يمكنك استخدام كل معدِّل على حدة أو الجمع بينها. أمثلة: استخدام المعدِّل نفسه عدة مرات.
SELECT COLUMNS('[jk]') APPLY(toString) APPLY(length) APPLY(max) FROM columns_transformers;
┌─max(length(toString(j)))─┬─max(length(toString(k)))─┐
│                        2 │                        3 │
└──────────────────────────┴──────────────────────────┘
استخدام عدة معدِّلات في استعلام واحد.
SELECT * REPLACE(i + 1 AS i) EXCEPT (j) APPLY(sum) from columns_transformers;
┌─sum(plus(i, 1))─┬─sum(k)─┐
│             222 │    347 │
└─────────────────┴────────┘

الإعدادات في استعلام SELECT

يمكنك تحديد الإعدادات اللازمة مباشرةً داخل استعلام SELECT. ولا تُطبَّق قيمة الإعداد إلا على هذا الاستعلام، ثم تُعاد إلى القيمة الافتراضية أو إلى القيمة السابقة بعد تنفيذ الاستعلام. للتعرّف على طرق أخرى لضبط الإعدادات، راجع هنا. بالنسبة إلى الإعدادات المنطقية المعيّنة إلى true، يمكنك استخدام صيغة مختصرة بحذف تعيين القيمة. وعند تحديد اسم الإعداد فقط، يُعيَّن تلقائيًا إلى 1 (صواب). مثال
SELECT * FROM some_table SETTINGS optimize_read_in_order=1, cast_keep_nullable=1;
آخر تعديل في ٢٥ يونيو ٢٠٢٦