تتضمن عبارة ORDER BY ما يلي:
- قائمة من التعبيرات، مثل
ORDER BY visits, search_phrase,
- قائمة من الأرقام التي تشير إلى الأعمدة في عبارة
SELECT، مثل ORDER BY 2, 1، أو
ALL، وتعني جميع أعمدة عبارة SELECT، مثل ORDER BY ALL.
لتعطيل الفرز حسب أرقام الأعمدة، اضبط الإعداد enable_positional_arguments = 0.
ولتعطيل الفرز حسب ALL، اضبط الإعداد enable_order_by_all = 0.
يمكن أن تقترن عبارة ORDER BY بالمُعدِّل DESC (تنازلي) أو ASC (تصاعدي)، والذي يحدد اتجاه الفرز.
ما لم يُحدَّد ترتيب فرز صريح، يُستخدم ASC افتراضيًا.
وينطبق اتجاه الفرز على تعبير واحد، لا على القائمة بأكملها، مثل ORDER BY Visits DESC, SearchPhrase.
كذلك، يُجرى الفرز مع مراعاة حالة الأحرف.
تُعاد الصفوف ذات القيم المتطابقة في تعبيرات الفرز بترتيب عشوائي وغير حتمي.
وإذا حُذفت عبارة ORDER BY من جملة SELECT، فسيكون ترتيب الصفوف أيضًا عشوائيًا وغير حتمي.
هناك نهجان لترتيب NaN وNULL عند الفرز:
- افتراضيًا أو مع المُعدِّل
NULLS LAST: تأتي القيم أولًا، ثم NaN، ثم NULL.
- مع المُعدِّل
NULLS FIRST: يأتي NULL أولًا، ثم NaN، ثم القيم الأخرى.
للجدول
┌─x─┬────y─┐
│ 1 │ ᴺᵁᴸᴸ │
│ 2 │ 2 │
│ 1 │ nan │
│ 2 │ 2 │
│ 3 │ 4 │
│ 5 │ 6 │
│ 6 │ nan │
│ 7 │ ᴺᵁᴸᴸ │
│ 6 │ 7 │
│ 8 │ 9 │
└───┴──────┘
نفّذ الاستعلام SELECT * FROM t_null_nan ORDER BY y NULLS FIRST للحصول على:
┌─x─┬────y─┐
│ 1 │ ᴺᵁᴸᴸ │
│ 7 │ ᴺᵁᴸᴸ │
│ 1 │ nan │
│ 6 │ nan │
│ 2 │ 2 │
│ 2 │ 2 │
│ 3 │ 4 │
│ 5 │ 6 │
│ 6 │ 7 │
│ 8 │ 9 │
└───┴──────┘
عند فرز الأعداد ذات الفاصلة العائمة، تكون قيم NaN منفصلة عن القيم الأخرى. وبغضّ النظر عن ترتيب الفرز، تأتي قيم NaN في النهاية. وبعبارة أخرى، عند الفرز تصاعديًا تُوضَع كما لو كانت أكبر من جميع الأعداد الأخرى، بينما عند الفرز تنازليًا تُوضَع كما لو كانت أصغر من سائر القيم.
لفرز قيم String، يمكنك تحديد قواعد الترتيب (المقارنة). مثال: ORDER BY SearchPhrase COLLATE 'tr' - لفرز keyword بترتيب تصاعدي باستخدام الأبجدية التركية، مع تجاهل حالة الأحرف، على افتراض أن السلاسل مرمّزة بترميز UTF-8. يمكن تحديد COLLATE أو عدم تحديده لكل تعبير في ORDER BY بشكل مستقل. إذا تم تحديد ASC أو DESC، فيتم وضع COLLATE بعده. عند استخدام COLLATE، يكون الفرز دائمًا غير حساس لحالة الأحرف.
تدعم LowCardinality وNullable وArray وTuple استخدام COLLATE.
نوصي باستخدام COLLATE فقط للفرز النهائي لعدد صغير من الصفوف، لأن الفرز باستخدام COLLATE أقل كفاءة من الفرز العادي حسب البايتات.
مثال يقتصر على قيم String فقط:
جدول الإدخال:
┌─x─┬─s────┐
│ 1 │ bca │
│ 2 │ ABC │
│ 3 │ 123a │
│ 4 │ abc │
│ 5 │ BCA │
└───┴──────┘
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
┌─x─┬─s────┐
│ 3 │ 123a │
│ 4 │ abc │
│ 2 │ ABC │
│ 1 │ bca │
│ 5 │ BCA │
└───┴──────┘
مثال على Nullable:
جدول المُدخلات:
┌─x─┬─s────┐
│ 1 │ bca │
│ 2 │ ᴺᵁᴸᴸ │
│ 3 │ ABC │
│ 4 │ 123a │
│ 5 │ abc │
│ 6 │ ᴺᵁᴸᴸ │
│ 7 │ BCA │
└───┴──────┘
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
┌─x─┬─s────┐
│ 4 │ 123a │
│ 5 │ abc │
│ 3 │ ABC │
│ 1 │ bca │
│ 7 │ BCA │
│ 6 │ ᴺᵁᴸᴸ │
│ 2 │ ᴺᵁᴸᴸ │
└───┴──────┘
مثال باستخدام Array:
جدول الإدخال:
┌─x─┬─s─────────────┐
│ 1 │ ['Z'] │
│ 2 │ ['z'] │
│ 3 │ ['a'] │
│ 4 │ ['A'] │
│ 5 │ ['z','a'] │
│ 6 │ ['z','a','a'] │
│ 7 │ [''] │
└───┴───────────────┘
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
┌─x─┬─s─────────────┐
│ 7 │ [''] │
│ 3 │ ['a'] │
│ 4 │ ['A'] │
│ 2 │ ['z'] │
│ 5 │ ['z','a'] │
│ 6 │ ['z','a','a'] │
│ 1 │ ['Z'] │
└───┴───────────────┘
مثال باستخدام سلسلة نصية LowCardinality:
جدول الإدخال:
┌─x─┬─s───┐
│ 1 │ Z │
│ 2 │ z │
│ 3 │ a │
│ 4 │ A │
│ 5 │ za │
│ 6 │ zaa │
│ 7 │ │
└───┴─────┘
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
┌─x─┬─s───┐
│ 7 │ │
│ 3 │ a │
│ 4 │ A │
│ 2 │ z │
│ 1 │ Z │
│ 5 │ za │
│ 6 │ zaa │
└───┴─────┘
مثال على Tuple:
┌─x─┬─s───────┐
│ 1 │ (1,'Z') │
│ 2 │ (1,'z') │
│ 3 │ (1,'a') │
│ 4 │ (2,'z') │
│ 5 │ (1,'A') │
│ 6 │ (2,'Z') │
│ 7 │ (2,'A') │
└───┴─────────┘
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
┌─x─┬─s───────┐
│ 3 │ (1,'a') │
│ 5 │ (1,'A') │
│ 2 │ (1,'z') │
│ 1 │ (1,'Z') │
│ 7 │ (2,'A') │
│ 4 │ (2,'z') │
│ 6 │ (2,'Z') │
└───┴─────────┘
يُستخدم قدر أقل من ذاكرة RAM إذا جرى تحديد LIMIT صغير بما يكفي إلى جانب ORDER BY. بخلاف ذلك، تكون كمية الذاكرة المستخدمة متناسبة مع حجم البيانات المطلوب فرزها. في المعالجة الموزعة للاستعلامات، إذا تم حذف GROUP BY، يُنفَّذ جزء من الفرز على الخوادم البعيدة، ثم تُدمَج النتائج على الخادم الذي أرسل الطلب. وهذا يعني أنه في الفرز الموزع قد يكون حجم البيانات المطلوب فرزها أكبر من مقدار الذاكرة المتاح على خادم واحد.
إذا لم تكن ذاكرة RAM كافية، فمن الممكن إجراء الفرز باستخدام الذاكرة الخارجية (بإنشاء ملفات مؤقتة على قرص). استخدم الإعداد max_bytes_before_external_sort لهذا الغرض. إذا كانت قيمته 0 (وهي القيمة الافتراضية)، فسيتم تعطيل الفرز الخارجي. وإذا كان مفعّلًا، فعندما يصل حجم البيانات المطلوب فرزها إلى عدد البايتات المحدد، تُفرَز البيانات المجمَّعة وتُحفَظ في ملف مؤقت. وبعد قراءة جميع البيانات، تُدمَج جميع الملفات المفروزة وتُخرَج النتائج. تُكتَب الملفات في الدليل /var/lib/clickhouse/tmp/ ضمن config (افتراضيًا، ولكن يمكنك استخدام المعلمة tmp_path لتغيير هذا الإعداد). يمكنك أيضًا استخدام الكتابة إلى القرص فقط إذا تجاوز الاستعلام حدود الذاكرة؛ أي إن max_bytes_ratio_before_external_sort=0.6 سيؤدي إلى تفعيل الكتابة إلى القرص فقط عندما يبلغ الاستعلام 60% من حد الذاكرة (user/sever).
قد يستهلك تشغيل الاستعلام ذاكرة أكبر من max_bytes_before_external_sort. ولهذا السبب، يجب أن تكون قيمة هذا الإعداد أقل بكثير من max_memory_usage. على سبيل المثال، إذا كان لدى خادمك 128 غيغابايت من ذاكرة RAM وكنت بحاجة إلى تشغيل استعلام واحد، فاضبط max_memory_usage على 100 غيغابايت، وmax_bytes_before_external_sort على 80 غيغابايت.
يعمل الفرز الخارجي بكفاءة أقل بكثير من الفرز داخل ذاكرة RAM.
إذا كان لتعبير ORDER BY بادئة تتطابق مع مفتاح فرز الجدول، يمكنك تحسين الاستعلام باستخدام إعداد optimize_read_in_order.
عند تمكين إعداد optimize_read_in_order، يستخدم خادم ClickHouse فهرس الجدول ويقرأ البيانات وفق ترتيب مفتاح ORDER BY. يتيح ذلك تجنب قراءة جميع البيانات عند تحديد LIMIT. لذلك، تُعالَج الاستعلامات على البيانات الكبيرة ذات LIMIT صغير بشكل أسرع.
يعمل هذا التحسين مع كلٍّ من ASC وDESC، ولا يعمل مع بند GROUP BY ومُعدِّل FINAL معًا.
عند تعطيل إعداد optimize_read_in_order، لا يستخدم خادم ClickHouse فهرس الجدول أثناء معالجة استعلامات SELECT.
فكّر في تعطيل optimize_read_in_order يدويًا عند تشغيل استعلامات تحتوي على عبارة ORDER BY وLIMIT كبير وشرط WHERE يتطلب قراءة كمية هائلة من السجلات قبل العثور على البيانات المطلوبة.
التحسين مدعوم في محركات الجداول التالية:
في الجداول التي تستخدم المحرك MaterializedView، يعمل هذا التحسين مع العروض مثل SELECT ... FROM merge_tree_table ORDER BY pk. لكنه غير مدعوم في استعلامات مثل SELECT ... FROM view ORDER BY pk إذا كان استعلام العرض لا يحتوي على عبارة ORDER BY.
مُعدِّل ORDER BY Expr WITH FILL
يمكن أيضًا دمج هذا المُعدِّل مع مُعدِّل LIMIT … WITH TIES.
يمكن استخدام مُعدِّل WITH FILL بعد ORDER BY expr مع مَعلمات اختيارية هي FROM expr وTO expr وSTEP expr.
ستُملأ جميع القيم الناقصة في العمود expr بالتسلسل، وستُملأ الأعمدة الأخرى بالقيم الافتراضية.
لملء أعمدة متعددة، أضِف مُعدِّل WITH FILL مع مَعلمات اختيارية بعد اسم كل عمود في قسم ORDER BY.
ORDER BY expr [WITH FILL] [FROM const_expr] [TO const_expr] [STEP const_numeric_expr] [STALENESS const_numeric_expr], ... exprN [WITH FILL] [FROM expr] [TO expr] [STEP numeric_expr] [STALENESS numeric_expr]
[INTERPOLATE [(col [AS expr], ... colN [AS exprN])]]
يمكن تطبيق WITH FILL على الحقول ذات الأنواع Numeric (بجميع أنواع float وdecimal وint) أو الأنواع Date/DateTime. وعند تطبيقه على حقول String، تُملأ القيم المفقودة بسلاسل فارغة.
عندما لا يكون FROM const_expr محددًا، يستخدم تسلسل الملء الحد الأدنى لقيمة الحقل expr من ORDER BY.
عندما لا يكون TO const_expr محددًا، يستخدم تسلسل الملء الحد الأقصى لقيمة الحقل expr من ORDER BY.
عندما يكون STEP const_numeric_expr محددًا، يُفسَّر const_numeric_expr as is للأنواع الرقمية، وdays لنوع Date، وseconds لنوع DateTime. كما يدعم أيضًا نوع البيانات INTERVAL الذي يمثل فواصل زمنية للتاريخ والوقت.
عندما يتم إغفال STEP const_numeric_expr، يستخدم تسلسل الملء 1.0 للنوع الرقمي، و1 day لنوع Date، و1 second لنوع DateTime.
عندما يكون STALENESS const_numeric_expr محددًا، سينشئ الاستعلام صفوفًا إلى أن يتجاوز الفرق عن الصف السابق في البيانات الأصلية const_numeric_expr.
يمكن تطبيق INTERPOLATE على الأعمدة التي لا تشارك في ORDER BY WITH FILL. وتُملأ هذه الأعمدة استنادًا إلى قيم الحقول السابقة عبر تطبيق expr. وإذا لم يكن expr موجودًا، فستُكرَّر القيمة السابقة. ويؤدي إغفال القائمة إلى تضمين جميع الأعمدة المسموح بها.
مثال على استعلام بدون WITH FILL:
SELECT n, source FROM (
SELECT toFloat32(number % 10) AS n, 'original' AS source
FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n;
┌─n─┬─source───┐
│ 1 │ original │
│ 4 │ original │
│ 7 │ original │
└───┴──────────┘
الاستعلام نفسه بعد تطبيق المُعدِّل WITH FILL:
SELECT n, source FROM (
SELECT toFloat32(number % 10) AS n, 'original' AS source
FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5;
┌───n─┬─source───┐
│ 0 │ │
│ 0.5 │ │
│ 1 │ original │
│ 1.5 │ │
│ 2 │ │
│ 2.5 │ │
│ 3 │ │
│ 3.5 │ │
│ 4 │ original │
│ 4.5 │ │
│ 5 │ │
│ 5.5 │ │
│ 7 │ original │
└─────┴──────────┘
في حالة وجود عدة حقول في ORDER BY field2 WITH FILL, field1 WITH FILL، سيكون ترتيب الملء وفق ترتيب الحقول في عبارة ORDER BY.
مثال:
SELECT
toDate((number * 10) * 86400) AS d1,
toDate(number * 86400) AS d2,
'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
d2 WITH FILL,
d1 WITH FILL STEP 5;
┌───d1───────┬───d2───────┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-01 │ 1970-01-03 │ │
│ 1970-01-01 │ 1970-01-04 │ │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-01-01 │ 1970-01-06 │ │
│ 1970-01-01 │ 1970-01-07 │ │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
الحقل d1 لا يُملأ ولا يستخدم القيمة الافتراضية لأنّه لا توجد قيم متكررة في d2، ولا يمكن حساب تسلسل d1 بشكل صحيح.
الاستعلام التالي بعد تغيير الحقل في ORDER BY:
SELECT
toDate((number * 10) * 86400) AS d1,
toDate(number * 86400) AS d2,
'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
d1 WITH FILL STEP 5,
d2 WITH FILL;
┌───d1───────┬───d2───────┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-16 │ 1970-01-01 │ │
│ 1970-01-21 │ 1970-01-01 │ │
│ 1970-01-26 │ 1970-01-01 │ │
│ 1970-01-31 │ 1970-01-01 │ │
│ 1970-02-05 │ 1970-01-01 │ │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-02-15 │ 1970-01-01 │ │
│ 1970-02-20 │ 1970-01-01 │ │
│ 1970-02-25 │ 1970-01-01 │ │
│ 1970-03-02 │ 1970-01-01 │ │
│ 1970-03-07 │ 1970-01-01 │ │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
يستخدم الاستعلام التالي نوع البيانات INTERVAL بقيمة يوم واحد لكل قيمة بيانات يتم ملؤها في العمود d1:
SELECT
toDate((number * 10) * 86400) AS d1,
toDate(number * 86400) AS d2,
'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
d1 WITH FILL STEP INTERVAL 1 DAY,
d2 WITH FILL;
┌─────────d1─┬─────────d2─┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-12 │ 1970-01-01 │ │
│ 1970-01-13 │ 1970-01-01 │ │
│ 1970-01-14 │ 1970-01-01 │ │
│ 1970-01-15 │ 1970-01-01 │ │
│ 1970-01-16 │ 1970-01-01 │ │
│ 1970-01-17 │ 1970-01-01 │ │
│ 1970-01-18 │ 1970-01-01 │ │
│ 1970-01-19 │ 1970-01-01 │ │
│ 1970-01-20 │ 1970-01-01 │ │
│ 1970-01-21 │ 1970-01-01 │ │
│ 1970-01-22 │ 1970-01-01 │ │
│ 1970-01-23 │ 1970-01-01 │ │
│ 1970-01-24 │ 1970-01-01 │ │
│ 1970-01-25 │ 1970-01-01 │ │
│ 1970-01-26 │ 1970-01-01 │ │
│ 1970-01-27 │ 1970-01-01 │ │
│ 1970-01-28 │ 1970-01-01 │ │
│ 1970-01-29 │ 1970-01-01 │ │
│ 1970-01-30 │ 1970-01-01 │ │
│ 1970-01-31 │ 1970-01-01 │ │
│ 1970-02-01 │ 1970-01-01 │ │
│ 1970-02-02 │ 1970-01-01 │ │
│ 1970-02-03 │ 1970-01-01 │ │
│ 1970-02-04 │ 1970-01-01 │ │
│ 1970-02-05 │ 1970-01-01 │ │
│ 1970-02-06 │ 1970-01-01 │ │
│ 1970-02-07 │ 1970-01-01 │ │
│ 1970-02-08 │ 1970-01-01 │ │
│ 1970-02-09 │ 1970-01-01 │ │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-02-11 │ 1970-01-01 │ │
│ 1970-02-12 │ 1970-01-01 │ │
│ 1970-02-13 │ 1970-01-01 │ │
│ 1970-02-14 │ 1970-01-01 │ │
│ 1970-02-15 │ 1970-01-01 │ │
│ 1970-02-16 │ 1970-01-01 │ │
│ 1970-02-17 │ 1970-01-01 │ │
│ 1970-02-18 │ 1970-01-01 │ │
│ 1970-02-19 │ 1970-01-01 │ │
│ 1970-02-20 │ 1970-01-01 │ │
│ 1970-02-21 │ 1970-01-01 │ │
│ 1970-02-22 │ 1970-01-01 │ │
│ 1970-02-23 │ 1970-01-01 │ │
│ 1970-02-24 │ 1970-01-01 │ │
│ 1970-02-25 │ 1970-01-01 │ │
│ 1970-02-26 │ 1970-01-01 │ │
│ 1970-02-27 │ 1970-01-01 │ │
│ 1970-02-28 │ 1970-01-01 │ │
│ 1970-03-01 │ 1970-01-01 │ │
│ 1970-03-02 │ 1970-01-01 │ │
│ 1970-03-03 │ 1970-01-01 │ │
│ 1970-03-04 │ 1970-01-01 │ │
│ 1970-03-05 │ 1970-01-01 │ │
│ 1970-03-06 │ 1970-01-01 │ │
│ 1970-03-07 │ 1970-01-01 │ │
│ 1970-03-08 │ 1970-01-01 │ │
│ 1970-03-09 │ 1970-01-01 │ │
│ 1970-03-10 │ 1970-01-01 │ │
│ 1970-03-11 │ 1970-01-01 │ │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
مثال لاستعلام بدون STALENESS:
SELECT number AS key, 5 * number value, 'original' AS source
FROM numbers(16) WHERE key % 5 == 0
ORDER BY key WITH FILL;
┌─key─┬─value─┬─source───┐
1. │ 0 │ 0 │ original │
2. │ 1 │ 0 │ │
3. │ 2 │ 0 │ │
4. │ 3 │ 0 │ │
5. │ 4 │ 0 │ │
6. │ 5 │ 25 │ original │
7. │ 6 │ 0 │ │
8. │ 7 │ 0 │ │
9. │ 8 │ 0 │ │
10. │ 9 │ 0 │ │
11. │ 10 │ 50 │ original │
12. │ 11 │ 0 │ │
13. │ 12 │ 0 │ │
14. │ 13 │ 0 │ │
15. │ 14 │ 0 │ │
16. │ 15 │ 75 │ original │
└─────┴───────┴──────────┘
الاستعلام نفسه بعد تطبيق STALENESS 3:
SELECT number AS key, 5 * number value, 'original' AS source
FROM numbers(16) WHERE key % 5 == 0
ORDER BY key WITH FILL STALENESS 3;
┌─key─┬─value─┬─source───┐
1. │ 0 │ 0 │ original │
2. │ 1 │ 0 │ │
3. │ 2 │ 0 │ │
4. │ 5 │ 25 │ original │
5. │ 6 │ 0 │ │
6. │ 7 │ 0 │ │
7. │ 10 │ 50 │ original │
8. │ 11 │ 0 │ │
9. │ 12 │ 0 │ │
10. │ 15 │ 75 │ original │
11. │ 16 │ 0 │ │
12. │ 17 │ 0 │ │
└─────┴───────┴──────────┘
مثال لاستعلام بدون INTERPOLATE:
SELECT n, source, inter FROM (
SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter
FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5;
┌───n─┬─source───┬─inter─┐
│ 0 │ │ 0 │
│ 0.5 │ │ 0 │
│ 1 │ original │ 1 │
│ 1.5 │ │ 0 │
│ 2 │ │ 0 │
│ 2.5 │ │ 0 │
│ 3 │ │ 0 │
│ 3.5 │ │ 0 │
│ 4 │ original │ 4 │
│ 4.5 │ │ 0 │
│ 5 │ │ 0 │
│ 5.5 │ │ 0 │
│ 7 │ original │ 7 │
└─────┴──────────┴───────┘
الاستعلام نفسه بعد تطبيق INTERPOLATE:
SELECT n, source, inter FROM (
SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter
FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5 INTERPOLATE (inter AS inter + 1);
┌───n─┬─source───┬─inter─┐
│ 0 │ │ 0 │
│ 0.5 │ │ 0 │
│ 1 │ original │ 1 │
│ 1.5 │ │ 2 │
│ 2 │ │ 3 │
│ 2.5 │ │ 4 │
│ 3 │ │ 5 │
│ 3.5 │ │ 6 │
│ 4 │ original │ 4 │
│ 4.5 │ │ 5 │
│ 5 │ │ 6 │
│ 5.5 │ │ 7 │
│ 7 │ original │ 7 │
└─────┴──────────┴───────┘
الملء للمجموعات بحسب بادئة الترتيب
قد يكون من المفيد ملء الصفوف التي تتطابق قيمها في أعمدة معيّنة بشكل مستقل — ومن الأمثلة الجيدة على ذلك ملء القيم المفقودة في السلاسل الزمنية.
لنفترض وجود جدول السلاسل الزمنية التالي:
CREATE TABLE timeseries
(
`sensor_id` UInt64,
`timestamp` DateTime64(3, 'UTC'),
`value` Float64
)
ENGINE = Memory;
SELECT * FROM timeseries;
┌─sensor_id─┬───────────────timestamp─┬─value─┐
│ 234 │ 2021-12-01 00:00:03.000 │ 3 │
│ 432 │ 2021-12-01 00:00:01.000 │ 1 │
│ 234 │ 2021-12-01 00:00:07.000 │ 7 │
│ 432 │ 2021-12-01 00:00:05.000 │ 5 │
└───────────┴─────────────────────────┴───────┘
ونودّ ملء القيم المفقودة لكل مستشعر بشكل مستقل وعلى فواصل زمنية قدرها ثانية واحدة.
ولتحقيق ذلك، نستخدم العمود sensor_id كبادئة للفرز للعمود timestamp عند الملء:
SELECT *
FROM timeseries
ORDER BY
sensor_id,
timestamp WITH FILL
INTERPOLATE ( value AS 9999 )
┌─sensor_id─┬───────────────timestamp─┬─value─┐
│ 234 │ 2021-12-01 00:00:03.000 │ 3 │
│ 234 │ 2021-12-01 00:00:04.000 │ 9999 │
│ 234 │ 2021-12-01 00:00:05.000 │ 9999 │
│ 234 │ 2021-12-01 00:00:06.000 │ 9999 │
│ 234 │ 2021-12-01 00:00:07.000 │ 7 │
│ 432 │ 2021-12-01 00:00:01.000 │ 1 │
│ 432 │ 2021-12-01 00:00:02.000 │ 9999 │
│ 432 │ 2021-12-01 00:00:03.000 │ 9999 │
│ 432 │ 2021-12-01 00:00:04.000 │ 9999 │
│ 432 │ 2021-12-01 00:00:05.000 │ 5 │
└───────────┴─────────────────────────┴───────┘
هنا، جرى إدراج القيمة 9999 في العمود value فقط لجعل الصفوف التي جرى ملؤها أكثر وضوحًا.
يُتحكَّم في هذا السلوك عبر ضبط use_with_fill_by_sorting_prefix (مفعّل افتراضيًا)
آخر تعديل في ٢٥ يونيو ٢٠٢٦