> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-fbfa8bee.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> توثيق عبارة ORDER BY

# عبارة ORDER BY

تتضمن عبارة `ORDER BY` ما يلي:

* قائمة من التعبيرات، مثل `ORDER BY visits, search_phrase`,
* قائمة من الأرقام التي تشير إلى الأعمدة في عبارة `SELECT`، مثل `ORDER BY 2, 1`، أو
* `ALL`، وتعني جميع أعمدة عبارة `SELECT`، مثل `ORDER BY ALL`.

لتعطيل الفرز حسب أرقام الأعمدة، اضبط الإعداد [enable\_positional\_arguments](/ar/reference/settings/session-settings#enable_positional_arguments) = 0.
ولتعطيل الفرز حسب `ALL`، اضبط الإعداد [enable\_order\_by\_all](/ar/reference/settings/session-settings#enable_order_by_all) = 0.

يمكن أن تقترن عبارة `ORDER BY` بالمُعدِّل `DESC` (تنازلي) أو `ASC` (تصاعدي)، والذي يحدد اتجاه الفرز.
ما لم يُحدَّد ترتيب فرز صريح، يُستخدم `ASC` افتراضيًا.
وينطبق اتجاه الفرز على تعبير واحد، لا على القائمة بأكملها، مثل `ORDER BY Visits DESC, SearchPhrase`.
كذلك، يُجرى الفرز مع مراعاة حالة الأحرف.

تُعاد الصفوف ذات القيم المتطابقة في تعبيرات الفرز بترتيب عشوائي وغير حتمي.
وإذا حُذفت عبارة `ORDER BY` من جملة `SELECT`، فسيكون ترتيب الصفوف أيضًا عشوائيًا وغير حتمي.

<div id="sorting-of-special-values">
  ## فرز القيم الخاصة
</div>

هناك نهجان لترتيب `NaN` و`NULL` عند الفرز:

* افتراضيًا أو مع المُعدِّل `NULLS LAST`: تأتي القيم أولًا، ثم `NaN`، ثم `NULL`.
* مع المُعدِّل `NULLS FIRST`: يأتي `NULL` أولًا، ثم `NaN`، ثم القيم الأخرى.

<div id="example">
  ### مثال
</div>

للجدول

```text theme={null}
┌─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` للحصول على:

```text theme={null}
┌─x─┬────y─┐
│ 1 │ ᴺᵁᴸᴸ │
│ 7 │ ᴺᵁᴸᴸ │
│ 1 │  nan │
│ 6 │  nan │
│ 2 │    2 │
│ 2 │    2 │
│ 3 │    4 │
│ 5 │    6 │
│ 6 │    7 │
│ 8 │    9 │
└───┴──────┘
```

عند فرز الأعداد ذات الفاصلة العائمة، تكون قيم `NaN` منفصلة عن القيم الأخرى. وبغضّ النظر عن ترتيب الفرز، تأتي قيم `NaN` في النهاية. وبعبارة أخرى، عند الفرز تصاعديًا تُوضَع كما لو كانت أكبر من جميع الأعداد الأخرى، بينما عند الفرز تنازليًا تُوضَع كما لو كانت أصغر من سائر القيم.

<div id="collation-support">
  ## دعم قواعد الترتيب
</div>

لفرز قيم [String](/ar/reference/data-types/string)، يمكنك تحديد قواعد الترتيب (المقارنة). مثال: `ORDER BY SearchPhrase COLLATE 'tr'` - لفرز `keyword` بترتيب تصاعدي باستخدام الأبجدية التركية، مع تجاهل حالة الأحرف، على افتراض أن السلاسل مرمّزة بترميز UTF-8. يمكن تحديد `COLLATE` أو عدم تحديده لكل تعبير في ORDER BY بشكل مستقل. إذا تم تحديد `ASC` أو `DESC`، فيتم وضع `COLLATE` بعده. عند استخدام `COLLATE`، يكون الفرز دائمًا غير حساس لحالة الأحرف.

تدعم [LowCardinality](/ar/reference/data-types/lowcardinality) و[Nullable](/ar/reference/data-types/nullable) و[Array](/ar/reference/data-types/array) و[Tuple](/ar/reference/data-types/tuple) استخدام `COLLATE`.

نوصي باستخدام `COLLATE` فقط للفرز النهائي لعدد صغير من الصفوف، لأن الفرز باستخدام `COLLATE` أقل كفاءة من الفرز العادي حسب البايتات.

<div id="collation-examples">
  ## أمثلة على قواعد الترتيب
</div>

مثال يقتصر على قيم [String](/ar/reference/data-types/string) فقط:

جدول الإدخال:

```text theme={null}
┌─x─┬─s────┐
│ 1 │ bca  │
│ 2 │ ABC  │
│ 3 │ 123a │
│ 4 │ abc  │
│ 5 │ BCA  │
└───┴──────┘
```

```sql title="Query" theme={null}
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
```

```text title="Response" theme={null}
┌─x─┬─s────┐
│ 3 │ 123a │
│ 4 │ abc  │
│ 2 │ ABC  │
│ 1 │ bca  │
│ 5 │ BCA  │
└───┴──────┘
```

مثال على [Nullable](/ar/reference/data-types/nullable):

جدول المُدخلات:

```text theme={null}
┌─x─┬─s────┐
│ 1 │ bca  │
│ 2 │ ᴺᵁᴸᴸ │
│ 3 │ ABC  │
│ 4 │ 123a │
│ 5 │ abc  │
│ 6 │ ᴺᵁᴸᴸ │
│ 7 │ BCA  │
└───┴──────┘
```

```sql title="Query" theme={null}
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
```

```text title="Response" theme={null}
┌─x─┬─s────┐
│ 4 │ 123a │
│ 5 │ abc  │
│ 3 │ ABC  │
│ 1 │ bca  │
│ 7 │ BCA  │
│ 6 │ ᴺᵁᴸᴸ │
│ 2 │ ᴺᵁᴸᴸ │
└───┴──────┘
```

مثال باستخدام [Array](/ar/reference/data-types/array):

جدول الإدخال:

```text theme={null}
┌─x─┬─s─────────────┐
│ 1 │ ['Z']         │
│ 2 │ ['z']         │
│ 3 │ ['a']         │
│ 4 │ ['A']         │
│ 5 │ ['z','a']     │
│ 6 │ ['z','a','a'] │
│ 7 │ ['']          │
└───┴───────────────┘
```

```sql title="Query" theme={null}
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
```

```text title="Response" theme={null}
┌─x─┬─s─────────────┐
│ 7 │ ['']          │
│ 3 │ ['a']         │
│ 4 │ ['A']         │
│ 2 │ ['z']         │
│ 5 │ ['z','a']     │
│ 6 │ ['z','a','a'] │
│ 1 │ ['Z']         │
└───┴───────────────┘
```

مثال باستخدام سلسلة نصية [LowCardinality](/ar/reference/data-types/lowcardinality):

جدول الإدخال:

```response theme={null}
┌─x─┬─s───┐
│ 1 │ Z   │
│ 2 │ z   │
│ 3 │ a   │
│ 4 │ A   │
│ 5 │ za  │
│ 6 │ zaa │
│ 7 │     │
└───┴─────┘
```

```sql title="Query" theme={null}
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
```

```response title="Response" theme={null}
┌─x─┬─s───┐
│ 7 │     │
│ 3 │ a   │
│ 4 │ A   │
│ 2 │ z   │
│ 1 │ Z   │
│ 5 │ za  │
│ 6 │ zaa │
└───┴─────┘
```

مثال على [Tuple](/ar/reference/data-types/tuple):

```response title="Response" theme={null}
┌─x─┬─s───────┐
│ 1 │ (1,'Z') │
│ 2 │ (1,'z') │
│ 3 │ (1,'a') │
│ 4 │ (2,'z') │
│ 5 │ (1,'A') │
│ 6 │ (2,'Z') │
│ 7 │ (2,'A') │
└───┴─────────┘
```

```sql title="Query" theme={null}
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
```

```response title="Response" theme={null}
┌─x─┬─s───────┐
│ 3 │ (1,'a') │
│ 5 │ (1,'A') │
│ 2 │ (1,'z') │
│ 1 │ (1,'Z') │
│ 7 │ (2,'A') │
│ 4 │ (2,'z') │
│ 6 │ (2,'Z') │
└───┴─────────┘
```

<div id="implementation-details">
  ## تفاصيل التنفيذ
</div>

يُستخدم قدر أقل من ذاكرة RAM إذا جرى تحديد [LIMIT](/ar/reference/statements/select/limit) صغير بما يكفي إلى جانب `ORDER BY`. بخلاف ذلك، تكون كمية الذاكرة المستخدمة متناسبة مع حجم البيانات المطلوب فرزها. في المعالجة الموزعة للاستعلامات، إذا تم حذف [GROUP BY](/ar/reference/statements/select/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.

<div id="optimization-of-data-reading">
  ## تحسين قراءة البيانات
</div>

إذا كان لتعبير `ORDER BY` بادئة تتطابق مع مفتاح فرز الجدول، يمكنك تحسين الاستعلام باستخدام إعداد [optimize\_read\_in\_order](/ar/reference/settings/session-settings#optimize_read_in_order).

عند تمكين إعداد `optimize_read_in_order`، يستخدم خادم ClickHouse فهرس الجدول ويقرأ البيانات وفق ترتيب مفتاح `ORDER BY`. يتيح ذلك تجنب قراءة جميع البيانات عند تحديد [LIMIT](/ar/reference/statements/select/limit). لذلك، تُعالَج الاستعلامات على البيانات الكبيرة ذات `LIMIT` صغير بشكل أسرع.

يعمل هذا التحسين مع كلٍّ من `ASC` و`DESC`، ولا يعمل مع بند [GROUP BY](/ar/reference/statements/select/group-by) ومُعدِّل [FINAL](/ar/reference/statements/select/from#final-modifier) معًا.

عند تعطيل إعداد `optimize_read_in_order`، لا يستخدم خادم ClickHouse فهرس الجدول أثناء معالجة استعلامات `SELECT`.

فكّر في تعطيل `optimize_read_in_order` يدويًا عند تشغيل استعلامات تحتوي على عبارة `ORDER BY` و`LIMIT` كبير وشرط [WHERE](/ar/reference/statements/select/where) يتطلب قراءة كمية هائلة من السجلات قبل العثور على البيانات المطلوبة.

التحسين مدعوم في محركات الجداول التالية:

* [MergeTree](/ar/reference/engines/table-engines/mergetree-family/mergetree) (بما في ذلك [materialized views](/ar/reference/statements/create/view#materialized-view)),
* [Merge](/ar/reference/engines/table-engines/special/merge),
* [Buffer](/ar/reference/engines/table-engines/special/buffer)

في الجداول التي تستخدم المحرك `MaterializedView`، يعمل هذا التحسين مع العروض مثل `SELECT ... FROM merge_tree_table ORDER BY pk`. لكنه غير مدعوم في استعلامات مثل `SELECT ... FROM view ORDER BY pk` إذا كان استعلام العرض لا يحتوي على عبارة `ORDER BY`.

<div id="order-by-expr-with-fill-modifier">
  ## مُعدِّل ORDER BY Expr WITH FILL
</div>

يمكن أيضًا دمج هذا المُعدِّل مع [مُعدِّل LIMIT ... WITH TIES](/ar/reference/statements/select/limit#limit--with-ties-modifier).

يمكن استخدام مُعدِّل `WITH FILL` بعد `ORDER BY expr` مع مَعلمات اختيارية هي `FROM expr` و`TO expr` و`STEP expr`.
ستُملأ جميع القيم الناقصة في العمود `expr` بالتسلسل، وستُملأ الأعمدة الأخرى بالقيم الافتراضية.

لملء أعمدة متعددة، أضِف مُعدِّل `WITH FILL` مع مَعلمات اختيارية بعد اسم كل عمود في قسم `ORDER BY`.

```sql title="Query" theme={null}
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](/ar/reference/data-types/special-data-types/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`:

```sql title="Query" theme={null}
SELECT n, source FROM (
   SELECT toFloat32(number % 10) AS n, 'original' AS source
   FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n;
```

```text title="Response" theme={null}
┌─n─┬─source───┐
│ 1 │ original │
│ 4 │ original │
│ 7 │ original │
└───┴──────────┘
```

الاستعلام نفسه بعد تطبيق المُعدِّل `WITH FILL`:

```sql title="Query" theme={null}
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;
```

```text title="Response" theme={null}
┌───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`.

مثال:

```sql title="Query" theme={null}
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;
```

```text title="Response" theme={null}
┌───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`:

```sql title="Query" theme={null}
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;
```

```text title="Response" theme={null}
┌───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`:

```sql title="Query" theme={null}
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;
```

```response title="Response" theme={null}
┌─────────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`:

```sql title="Query" theme={null}
SELECT number AS key, 5 * number value, 'original' AS source
FROM numbers(16) WHERE key % 5 == 0
ORDER BY key WITH FILL;
```

```text title="Response" theme={null}
    ┌─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`:

```sql title="Query" theme={null}
SELECT number AS key, 5 * number value, 'original' AS source
FROM numbers(16) WHERE key % 5 == 0
ORDER BY key WITH FILL STALENESS 3;
```

```text title="Response" theme={null}
    ┌─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`:

```sql title="Query" theme={null}
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;
```

```text title="Response" theme={null}
┌───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`:

```sql title="Query" theme={null}
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);
```

```text title="Response" theme={null}
┌───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 │
└─────┴──────────┴───────┘
```

<div id="filling-grouped-by-sorting-prefix">
  ## الملء للمجموعات بحسب بادئة الترتيب
</div>

قد يكون من المفيد ملء الصفوف التي تتطابق قيمها في أعمدة معيّنة بشكل مستقل — ومن الأمثلة الجيدة على ذلك ملء القيم المفقودة في السلاسل الزمنية.
لنفترض وجود جدول السلاسل الزمنية التالي:

```sql theme={null}
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` عند الملء:

```sql theme={null}
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` (مفعّل افتراضيًا)

<div id="related-content">
  ## محتوى ذو صلة
</div>

* المدونة: [العمل مع بيانات السلاسل الزمنية في ClickHouse](https://clickhouse.com/blog/working-with-time-series-data-and-functions-ClickHouse)
