الانتقال إلى المحتوى الرئيسي
يحوّل ClickHouse المعاملات إلى الدوال المقابلة لها في مرحلة تحليل الاستعلام وفقًا لأولويتها وأسبقيتها وترابطها.

معاملات الوصول

a[N] – الوصول إلى عنصر في مصفوفة. الدالة arrayElement(a, N). a.N – الوصول إلى عنصر في tuple. الدالة tupleElement(a, N).

معامل النفي العددي

-a – الدالة negate (a). لنفي tuple: tupleNegate.

معاملات الضرب والقسمة

a * b – الدالة multiply (a, b). لضرب Tuple في عدد: tupleMultiplyByNumber، ولحساب حاصل الضرب القياسي: dotProduct. a / b – الدالة divide(a, b). لقسمة Tuple على عدد: tupleDivideByNumber. a % b – الدالة modulo(a, b).

معاملات الجمع والطرح

a + b – الدالة plus(a, b). لجمع قيم Tuple: tuplePlus. a - b – الدالة minus(a, b). لطرح قيم Tuple: tupleMinus.

معاملات المقارنة

دالة equals

a = b – دالة equals(a, b). a == b – دالة equals(a, b).

دالة notEquals

a != b – الدالة notEquals(a, b). a <> b – الدالة notEquals(a, b).

دالة lessOrEquals

a <= b – هي الدالة lessOrEquals(a, b).

دالة greaterOrEquals

a >= b – تمثلها الدالة greaterOrEquals(a, b).

دالة less

a < b – الدالة less(a, b).

الدالة greater

a > b – الدالة greater(a, b).

الدالة like

a LIKE b – الدالة like(a, b).

دالة notLike

a NOT LIKE b – الدالة notLike(a, b).

دالة ilike

a ILIKE b – هي الدالة ilike(a, b).

دالة BETWEEN

a BETWEEN b AND c – تعادل a >= b AND a <= c. a NOT BETWEEN b AND c – تعادل a < b OR a > c.

معامل “ليس مختلفًا عن” (<=>)

اعتبارًا من الإصدار 25.10، يمكنك استخدام <=> بالطريقة نفسها التي تستخدم بها أي معامل آخر. قبل الإصدار 25.10، لم يكن بالإمكان استخدامه إلا في تعبيرات JOIN، على سبيل المثال:
CREATE TABLE a (x String) ENGINE = Memory;
INSERT INTO a VALUES ('ClickHouse');

SELECT * FROM a AS a1 JOIN a AS a2 ON a1.x <=> a2.x;

┌─x──────────┬─a2.x───────┐
│ ClickHouse │ ClickHouse │
└────────────┴────────────┘
المعامل <=> هو معامل مساواة آمن مع NULL، وهو مكافئ لـ IS NOT DISTINCT FROM. وهو يعمل مثل معامل المساواة العادي (=)، لكنه يتعامل مع قيم NULL على أنها قابلة للمقارنة. تُعدّ قيمتا NULL متساويتين، كما أن مقارنة NULL بأي قيمة غير NULL تُرجع 0 (false) بدلًا من NULL.
SELECT
  'ClickHouse' <=> NULL,
  NULL <=> NULL
┌─isNotDistinc⋯use', NULL)─┬─isNotDistinc⋯NULL, NULL)─┐
│                        0 │                        1 │
└──────────────────────────┴──────────────────────────┘

المعاملات الخاصة بالتعامل مع السلاسل النصية

OVERLAY

  • OVERLAY(string PLACING replacement FROM offset) - الدالة overlay(string, replacement, offset).
  • OVERLAY(string PLACING replacement FROM offset FOR length) - الدالة overlay(string, replacement, offset, length).
  • OVERLAYUTF8(string PLACING replacement FROM offset) - الدالة overlayUTF8(string, replacement, offset).
  • OVERLAYUTF8(string PLACING replacement FROM offset FOR length) - الدالة overlayUTF8(string, replacement, offset, length).

المعاملات الخاصة بالعمل مع مجموعات البيانات

راجع معاملات IN والمعامل EXISTS.

الدالة in

a IN ... – الدالة in(a, b).

دالة notIn

a NOT IN ... – الدالة notIn(a, b).

دالة globalIn

a GLOBAL IN ... – الدالة globalIn(a, b).

دالة globalNotIn

a GLOBAL NOT IN ... – الدالة globalNotIn(a, b).

دالة in للاستعلامات الفرعية

a = ANY (subquery) – وهي الدالة in(a, subquery).

notIn استعلام فرعي function

a != ANY (subquery) – وهو مماثل لـ a NOT IN (SELECT singleValueOrNull(*) FROM subquery).

دالة in استعلام فرعي

a = ALL (subquery) – هي نفسها a IN (SELECT singleValueOrNull(*) FROM subquery).

دالة notIn للاستعلام الفرعي

a != ALL (subquery) – الدالة notIn(a, subquery). أمثلة استعلام باستخدام ALL:
Query
SELECT number AS a FROM numbers(10) WHERE a > ALL (SELECT number FROM numbers(3, 3));
Response
┌─a─┐
│ 6 │
│ 7 │
│ 8 │
│ 9 │
└───┘
استعلام باستخدام ANY:
Query
SELECT number AS a FROM numbers(10) WHERE a > ANY (SELECT number FROM numbers(3, 3));
Response
┌─a─┐
│ 4 │
│ 5 │
│ 6 │
│ 7 │
│ 8 │
│ 9 │
└───┘

SOME / ALL على المصفوفات

بالإضافة إلى صيغة الاستعلام الفرعي الموضحة أعلاه، يمكن أن يكون الطرف الأيمن من SOME / ALL تعبيرَ مصفوفة (قيمة حرفية لمصفوفة، أو عمودًا من نوع مصفوفة، أو أي تعبير يُرجع مصفوفة). هذه هي صيغة مكمِّم المصفوفة بأسلوب PostgreSQL. ويُتعرَّف عليها أثناء التحليل وتُعاد كتابتها إلى دوال المصفوفات، لذلك لا حاجة إلى إعادة كتابتها يدويًا:
الصياغةتُعاد كتابتها إلى
expr = SOME(arr)has(arr, expr)
expr <> ALL(arr)NOT has(arr, expr)
expr OP SOME(arr) (أي عامل مقارنة آخر)arrayExists(x -> expr OP x, arr)
expr OP ALL(arr) (أي عامل مقارنة آخر)arrayAll(x -> expr OP x, arr)
يمثل SOME المكمِّم الوجودي (وهو المرادف في SQL لـ ANY). وتُعامَل = و <> كحالتين خاصتين وتُحوَّلان إلى has / NOT has لأن لهما تنفيذًا مُحسَّنًا؛ أما الصيغة العامة فتعتمد على الدالتين الأعلى ترتيبًا arrayExists / arrayAll. لا يُتعرَّف على صيغة المصفوفة إلا مع عوامل المقارنة =, ==, !=, <>, <=>, <, <=, >, و >=. أما العوامل الأخرى التي تقبل مصفوفة في الطرف الأيمن — مثل LIKE و ILIKE و NOT LIKE و REGEXP و IN — فلا تُعاد كتابتها إلى مكمِّم المصفوفة، وتحتفظ بمعناها المعتاد. على سبيل المثال، 'abc' LIKE SOME(['a%', 'b%']) ليست صيغة مكمِّم المصفوفة؛ استخدم arrayExists / arrayAll مباشرةً في تلك الحالات.
ANY غير مدعومة في صيغة المصفوفةلا يقبل الطرف الأيمن كمصفوفة إلا SOME و ALL. تُستبعَد ANY لأن any هي أيضًا دالة تجميع، لذلك يحتفظ التعبير بالشكل expr = any(x) بمعنى استدعاء الدالة. استخدم SOME لمكمِّم المصفوفة.
Query
SELECT
    3 = SOME([1, 2, 3, 4]) AS in_array,
    5 < SOME([1, 2, 6])    AS less_than_some,
    5 > ALL([1, 2, 3])     AS greater_than_all;
Response
┌─in_array─┬─less_than_some─┬─greater_than_all─┐
│        1 │              1 │                1 │
└──────────┴────────────────┴──────────────────┘
تختلف معالجة NULL عن صيغة الاستعلام الفرعيلأن صيغة المصفوفة يُعادَت صياغتها في المحلّل النحوي (حيث لا تكون إعدادات الاستعلام مثل transform_null_in متاحة، كما أن عمود المصفوفة على مستوى الصف لا يمكنه استخدام مسار IN الآمن مع NULL في المحلّل)، فإنها تستخدم الدلالات ثنائية القيمة لكل من has (مع = / <>) و arrayExists / arrayAll (اللذين يختزلان نتيجة مقارنة NULL غير المعروفة إلى 0). وقد يختلف ذلك عن صيغة الاستعلام الفرعي، إذ تُعالَج فيها NULL عبر IN / NOT IN وتعتمد على transform_null_in:
SELECT NULL = SOME([NULL]);   -- has([NULL], NULL)                  -> 1
SELECT NULL <> ALL([NULL]);   -- NOT has([NULL], NULL)              -> 0
SELECT NULL < SOME([1]);      -- arrayExists(x -> NULL < x, [1])    -> 0
SELECT NULL > ALL([1]);       -- arrayAll(x -> NULL > x, [1])       -> 0

المعاملات للعمل مع التواريخ والأوقات

EXTRACT

EXTRACT(part FROM date);
استخرج أجزاء من تاريخ معيّن. على سبيل المثال، يمكنك استخراج شهر من تاريخ معيّن، أو ثانية من وقت معيّن. تحدِّد المعلمة part أي جزء من التاريخ يجب استخراجه. القيم التالية متاحة:
  • NANOSECOND — النانوثانية. القيم الممكنة: 0–999999999.
  • MICROSECOND — الميكروثانية. القيم الممكنة: 0–999999.
  • MILLISECOND — الميلي ثانية. القيم الممكنة: 0–999.
  • SECOND — الثانية. القيم الممكنة: 0–59.
  • MINUTE — الدقيقة. القيم الممكنة: 0–59.
  • HOUR — الساعة. القيم الممكنة: 0–23.
  • DAY — يوم الشهر. القيم الممكنة: 1–31.
  • WEEK — رقم الأسبوع وفق معيار ISO 8601. القيم الممكنة: 1–53.
  • MONTH — رقم الشهر. القيم الممكنة: 1–12.
  • QUARTER — الربع. القيم الممكنة: 1–4.
  • YEAR — السنة.
  • EPOCH — الطابع الزمني لـ Unix (الثواني منذ 1970-01-01 00:00:00 UTC). ملاحظة: بالنسبة إلى DateTime64، يُقتطع الجزء الأقل من الثانية.
  • DOW — يوم الأسبوع (متوافق مع PostgreSQL). 0 = الأحد، 6 = السبت.
  • DOY — يوم السنة. القيم الممكنة: 1–366.
  • ISODOW — يوم الأسبوع وفق ISO. 1 = الاثنين، 7 = الأحد.
  • ISOYEAR — سنة ترقيم الأسابيع وفق ISO 8601.
  • CENTURY — القرن. على سبيل المثال، السنة 2024 تقع في القرن الحادي والعشرين.
  • DECADE — العقد (السنة مقسومة على 10). على سبيل المثال، السنة 2024 عقدها 202.
  • MILLENNIUM — الألفية. على سبيل المثال، السنة 2024 تقع في الألفية الثالثة.
  • TIMEZONE_HOUR — جزء الساعات الموقَّع من إزاحة UTC للمنطقة الزمنية الخاصة بالمعامل. على سبيل المثال، +5:30 تُرجع 5، و-3:30 تُرجع -3.
  • TIMEZONE_MINUTE — جزء الدقائق الموقَّع من إزاحة UTC للمنطقة الزمنية الخاصة بالمعامل. على سبيل المثال، +5:30 تُرجع 30، و-3:30 تُرجع -30.
المعلمة part غير حساسة لحالة الأحرف. تحدِّد المعلمة date القيمة المطلوب معالجتها. الأنواع Date وDate32 وDateTime وDateTime64 وInterval مدعومة. عندما تكون date من النوع Interval، يجب أن يطابق part المطلوب النوع المخزَّن في الـ interval (على سبيل المثال، يُسمح بـ EXTRACT(DAY FROM INTERVAL 5 DAY)؛ ويُرفَض EXTRACT(HOUR FROM INTERVAL 5 DAY)، لأن فواصل ClickHouse تكون من نوع واحد فقط). تكون نتيجة معامل Interval من النوع Int64. أمثلة:
SELECT EXTRACT(DAY FROM toDate('2017-06-15'));
SELECT EXTRACT(MONTH FROM toDate('2017-06-15'));
SELECT EXTRACT(YEAR FROM toDate('2017-06-15'));
SELECT EXTRACT(EPOCH FROM toDateTime('2024-01-15 12:30:45', 'UTC'));
SELECT EXTRACT(DOW FROM toDate('2024-01-15'));
SELECT EXTRACT(CENTURY FROM toDate('2024-01-01'));
SELECT EXTRACT(TIMEZONE_HOUR   FROM toDateTime('2024-01-15 12:00:00', 'Asia/Kolkata'));    -- 5
SELECT EXTRACT(TIMEZONE_MINUTE FROM toDateTime('2024-01-15 12:00:00', 'Asia/Kolkata'));    -- 30
SELECT EXTRACT(DAY   FROM INTERVAL 40 DAY);                                                -- 40
SELECT EXTRACT(MONTH FROM INTERVAL 7 MONTH);                                               -- 7
في المثال التالي، نُنشئ جدولًا ونُدرِج فيه قيمة من نوع DateTime.
CREATE TABLE test.Orders
(
    OrderId UInt64,
    OrderName String,
    OrderDate DateTime
) ENGINE = MergeTree
ORDER BY ();
INSERT INTO test.Orders VALUES (1, 'Jarlsberg Cheese', toDateTime('2008-10-11 13:23:44'));
SELECT
    toYear(OrderDate) AS OrderYear,
    toMonth(OrderDate) AS OrderMonth,
    toDayOfMonth(OrderDate) AS OrderDay,
    toHour(OrderDate) AS OrderHour,
    toMinute(OrderDate) AS OrderMinute,
    toSecond(OrderDate) AS OrderSecond
FROM test.Orders;
┌─OrderYear─┬─OrderMonth─┬─OrderDay─┬─OrderHour─┬─OrderMinute─┬─OrderSecond─┐
│      2008 │         10 │       11 │        13 │          23 │          44 │
└───────────┴────────────┴──────────┴───────────┴─────────────┴─────────────┘
يمكنك الاطلاع على المزيد من الأمثلة في الاختبارات.

INTERVAL

ينشئ قيمة من نوع Interval ينبغي استخدامها في العمليات الحسابية مع قيم من النوعين Date وDateTime. أنواع الفواصل الزمنية:
  • SECOND
  • MINUTE
  • HOUR
  • DAY
  • WEEK
  • MONTH
  • QUARTER
  • YEAR
يمكنك أيضًا استخدام قيمة حرفية نصية عند تعيين قيمة INTERVAL. على سبيل المثال، INTERVAL 1 HOUR مكافئ لـ INTERVAL '1 hour' أو INTERVAL '1' hour.
لا يمكن دمج الفواصل الزمنية ذات الأنواع المختلفة. لا يمكنك استخدام تعبيرات مثل INTERVAL 4 DAY 1 HOUR. حدِّد الفواصل الزمنية بوحدات أصغر من أصغر وحدة في الفاصل الزمني أو مساوية لها، على سبيل المثال INTERVAL 25 HOUR. ويمكنك استخدام عمليات متتالية، كما في المثال أدناه.
أمثلة:
SELECT now() AS current_date_time, current_date_time + INTERVAL 4 DAY + INTERVAL 3 HOUR;
┌───current_date_time─┬─plus(plus(now(), toIntervalDay(4)), toIntervalHour(3))─┐
│ 2020-11-03 22:09:50 │                                    2020-11-08 01:09:50 │
└─────────────────────┴────────────────────────────────────────────────────────┘
SELECT now() AS current_date_time, current_date_time + INTERVAL '4 day' + INTERVAL '3 hour';
┌───current_date_time─┬─plus(plus(now(), toIntervalDay(4)), toIntervalHour(3))─┐
│ 2020-11-03 22:12:10 │                                    2020-11-08 01:12:10 │
└─────────────────────┴────────────────────────────────────────────────────────┘
SELECT now() AS current_date_time, current_date_time + INTERVAL '4' day + INTERVAL '3' hour;
┌───current_date_time─┬─plus(plus(now(), toIntervalDay('4')), toIntervalHour('3'))─┐
│ 2020-11-03 22:33:19 │                                        2020-11-08 01:33:19 │
└─────────────────────┴────────────────────────────────────────────────────────────┘
يُفضَّل دائمًا استخدام صيغة INTERVAL أو الدالة addDays. أمّا الجمع أو الطرح البسيط (بصيغة مثل now() + ...) فلا يأخذ إعدادات التوقيت في الحسبان، مثل التوقيت الصيفي.
أمثلة:
SELECT toDateTime('2014-10-26 00:00:00', 'Asia/Istanbul') AS time, time + 60 * 60 * 24 AS time_plus_24_hours, time + toIntervalDay(1) AS time_plus_1_day;
┌────────────────time─┬──time_plus_24_hours─┬─────time_plus_1_day─┐
│ 2014-10-26 00:00:00 │ 2014-10-26 23:00:00 │ 2014-10-27 00:00:00 │
└─────────────────────┴─────────────────────┴─────────────────────┘
راجع أيضًا

إضافة التاريخ والوقت

يمكن إضافة قيمة Date أو Date32 إلى قيمة Time أو Time64 باستخدام المعامل +. وتكون النتيجة DateTime أو DateTime64، وتمثل التاريخ عند الوقت المحدد من اليوم. هذه العملية إبدالية. يعتمد نوع النتيجة على نوعَي المعاملين:
المعامل الأيسرالمعامل الأيمننوع النتيجة
DateTimeDateTime
DateTime64(s)DateTime64(s)
Date32TimeDateTime64(0)
Date32Time64(s)DateTime64(s)
تستخدم النتيجة المنطقة الزمنية للجلسة (أو المنطقة الزمنية الافتراضية للخادوم إذا لم يتم تعيين منطقة زمنية للجلسة). ويتحكم الإعداد date_time_overflow_behavior في ما يحدث عندما تكون النتيجة خارج النطاق القابل للتمثيل.
أمثلة:
SET use_legacy_to_time = 0;
SELECT toDate('2024-07-15') + toTime('14:30:25') AS dt, toTypeName(dt);
┌──────────────────dt─┬─toTypeName(dt)─┐
│ 2024-07-15 14:30:25 │ DateTime       │
└─────────────────────┴────────────────┘
SELECT toDate('2024-07-15') + toTime64('14:30:25.123456', 6) AS dt, toTypeName(dt);
┌─────────────────────────dt─┬─toTypeName(dt)─┐
│ 2024-07-15 14:30:25.123456 │ DateTime64(6)  │
└────────────────────────────┴────────────────┘
SELECT toTime64('23:59:59.999', 3) + toDate32('2024-07-15') AS dt, toTypeName(dt);
┌──────────────────────dt─┬─toTypeName(dt)─┐
│ 2024-07-15 23:59:59.999 │ DateTime64(3)  │
└─────────────────────────┴────────────────┘

المعامل المنطقي AND

الصياغة SELECT a AND b — تحسب الاقتران المنطقي لـ a وb باستخدام الدالة and.

معامل OR المنطقي

الصياغة SELECT a OR b — يحسب الفصل المنطقي لـ a وb باستخدام الدالة or.

معامل النفي المنطقي

الصياغة SELECT NOT a — تحسب النفي المنطقي لـ a باستخدام الدالة not.

المعامل الشرطي

a ? b : c – الدالة if(a, b, c). ملاحظة: يحسب المعامل الشرطي قيمتَي b و c، ثم يتحقق مما إذا كان الشرط a متحققًا، ثم يعيد القيمة المقابلة. إذا كانت b أو C دالة arrayJoin()، فسيُكرَّر كل صف بغض النظر عن الشرط “a”.

التعبير الشرطي

CASE [x]
    WHEN a THEN b
    [WHEN ... THEN ...]
    [ELSE c]
END
إذا كان x محددًا، فستُستخدم الدالة transform(x, [a, ...], [b, ...], c). وإلا فستُستخدم multiIf(a, b, ..., c). إذا لم تتضمن expression عبارة ELSE c، فستكون القيمة الافتراضية هي NULL. لا تعمل الدالة transform مع NULL.

معامل ربط السلاسل

s1 || s2 – دالة concat(s1, s2).

معامل إنشاء Lambda

x -> expr – الدالة lambda(x, expr). لا أولوية للمعاملات التالية لأنها أقواس:

معامل إنشاء المصفوفة

[x1, ...] – الدالة array(x1, ...).

معامل إنشاء Tuple

(x1, x2, ...) – الدالة tuple(x2, x2, ...).

الترابطية

تتمتع جميع المعاملات الثنائية بترابطية يسارية. على سبيل المثال، يُحوَّل 1 + 2 + 3 إلى plus(plus(1, 2), 3). وأحيانًا لا يعمل ذلك بالطريقة التي قد تتوقعها. فعلى سبيل المثال، تكون نتيجة SELECT 4 > 2 > 3 هي 0. ولتحسين الكفاءة، تقبل الدالتان and وor أي عدد من الوسائط. وتُحوَّل سلاسل المعاملات AND وOR المقابلة إلى استدعاء واحد لهاتين الدالتين.

التحقق من وجود NULL

يدعم ClickHouse العاملين IS NULL وIS NOT NULL.

IS NULL

  • بالنسبة إلى القيم من النوع Nullable، يعيد المعامل IS NULL ما يلي:
    • 1 إذا كانت القيمة NULL.
    • 0 بخلاف ذلك.
  • بالنسبة إلى القيم الأخرى، يعيد المعامل IS NULL دائمًا القيمة 0.
يمكن تحسين ذلك بتمكين الإعداد optimize_functions_to_subcolumns. عند ضبط optimize_functions_to_subcolumns = 1، تقرأ الدالة العمود الفرعي null فقط بدلًا من قراءة بيانات العمود بالكامل ومعالجتها. ويتحوّل الاستعلام SELECT n IS NULL FROM table إلى SELECT n.null FROM TABLE.
SELECT x+100 FROM t_null WHERE y IS NULL
┌─plus(x, 100)─┐
│          101 │
└──────────────┘

IS NOT NULL

  • بالنسبة إلى القيم من النوع Nullable، يعيد المعامل IS NOT NULL ما يلي:
    • 0 إذا كانت القيمة NULL.
    • 1 في غير ذلك.
  • بالنسبة إلى القيم الأخرى، يعيد المعامل IS NOT NULL دائمًا 1.
SELECT * FROM t_null WHERE y IS NOT NULL
┌─x─┬─y─┐
│ 2 │ 3 │
└───┴───┘
يمكن تحسين ذلك عبر تفعيل إعداد optimize_functions_to_subcolumns. عند ضبط optimize_functions_to_subcolumns = 1، لا تقرأ الدالة سوى العمود الفرعي null بدلًا من قراءة بيانات العمود بالكامل ومعالجتها. ويتحوّل الاستعلام SELECT n IS NOT NULL FROM table إلى SELECT NOT n.null FROM TABLE.

التحقق من القيم المنطقية

يدعم ClickHouse المعاملات IS TRUE وIS FALSE وIS UNKNOWN وIS NOT TRUE وIS NOT FALSE وIS NOT UNKNOWN. تُستخدم هذه المعاملات مع تعبيرات Bool وNullable(Bool).
  • يعيد expr IS TRUE القيمة 1 فقط إذا كانت قيمة expr هي true.
  • يعيد expr IS FALSE القيمة 1 فقط إذا كانت قيمة expr هي false.
  • يعيد expr IS UNKNOWN القيمة 1 فقط إذا كانت قيمة expr هي NULL.
  • يعيد expr IS NOT TRUE القيمة 1 إذا كانت قيمة expr هي false أو NULL.
  • يعيد expr IS NOT FALSE القيمة 1 إذا كانت قيمة expr هي true أو NULL.
  • يعيد expr IS NOT UNKNOWN القيمة 1 إذا لم تكن قيمة expr هي NULL.
بالنسبة إلى التعبيرات المنطقية، فإن IS UNKNOWN تكافئ IS NULL، وIS NOT UNKNOWN تكافئ IS NOT NULL.
CREATE TABLE t_bool (x Nullable(Bool)) ENGINE = Memory;
INSERT INTO t_bool VALUES (true), (false), (NULL);

SELECT
    x,
    x IS TRUE,
    x IS FALSE,
    x IS UNKNOWN,
    x IS NOT TRUE,
    x IS NOT FALSE,
    x IS NOT UNKNOWN
FROM t_bool;
آخر تعديل في ٢٩ يونيو ٢٠٢٦