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

> توثيق لعبارة DISTINCT

# DISTINCT

إذا تم تحديد `SELECT DISTINCT`، فلن تبقى في نتيجة الاستعلام إلا الصفوف المميزة. وبذلك، لن يبقى من بين جميع مجموعات الصفوف المتطابقة تمامًا في النتيجة سوى صف واحد فقط.

يمكنك تحديد قائمة الأعمدة التي يجب أن تكون قيمها مميزة: `SELECT DISTINCT ON (column1, column2,...)`. وإذا لم يتم تحديد الأعمدة، فستُؤخذ جميعها في الاعتبار.

لننظر إلى الجدول:

```text theme={null}
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 2 │ 2 │ 2 │
│ 1 │ 1 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘
```

استخدام `DISTINCT` من دون تحديد أعمدة:

```sql theme={null}
SELECT DISTINCT * FROM t1;
```

```text theme={null}
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 1 │ 1 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘
```

استخدام `DISTINCT` مع أعمدة محددة:

```sql theme={null}
SELECT DISTINCT ON (a,b) * FROM t1;
```

```text theme={null}
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘
```

## DISTINCT و ORDER BY

يدعم ClickHouse استخدام العبارتين `DISTINCT` و `ORDER BY` على أعمدة مختلفة ضمن استعلام واحد. وتُنفَّذ العبارة `DISTINCT` قبل العبارة `ORDER BY`.

انظر إلى الجدول التالي:

```text theme={null}
┌─a─┬─b─┐
│ 2 │ 1 │
│ 1 │ 2 │
│ 3 │ 3 │
│ 2 │ 4 │
└───┴───┘
```

اختيار البيانات:

```sql theme={null}
SELECT DISTINCT a FROM t1 ORDER BY b ASC;
```

```text theme={null}
┌─a─┐
│ 2 │
│ 1 │
│ 3 │
└───┘
```

اختيار البيانات باستخدام اتجاه فرز مختلف:

```sql theme={null}
SELECT DISTINCT a FROM t1 ORDER BY b DESC;
```

```text theme={null}
┌─a─┐
│ 3 │
│ 1 │
│ 2 │
└───┘
```

تم اقتطاع الصف `2, 4` قبل الفرز.

ضع هذه الخصوصية التنفيذية في الحسبان عند برمجة الاستعلامات.

## معالجة NULL

تعمل `DISTINCT` مع [NULL](/ar/reference/syntax#null) كما لو أن `NULL` قيمة محددة، وكأن `NULL==NULL`. وبعبارة أخرى، لا تظهر في نتائج `DISTINCT` التركيبات المختلفة التي تتضمن `NULL` إلا مرة واحدة فقط. وهذا يختلف عن طريقة التعامل مع `NULL` في معظم السياقات الأخرى.

## بدائل

يمكن الحصول على النتيجة نفسها بتطبيق [GROUP BY](/ar/reference/statements/select/group-by) على نفس مجموعة القيم المحددة في عبارة `SELECT`، من دون استخدام أي دوال تجميع. لكن توجد بعض الفروق مقارنةً بنهج `GROUP BY`:

* يمكن تطبيق `DISTINCT` مع `GROUP BY` في الوقت نفسه.
* قبل بدء التنفيذ الخارجي، يمكن للاستعلام من دون [ORDER BY](/ar/reference/statements/select/order-by) أن يتوقف فور قراءته عددًا كافيًا من الصفوف المختلفة لتلبية [LIMIT](/ar/reference/statements/select/limit).
* قبل بدء التنفيذ الخارجي وعند حذف `ORDER BY`، يمكن أيضًا لنطاق [`LIMIT ... AFTER ... UNTIL`](/ar/reference/statements/select/limit#limit-after-until) من دون `ALL` أن يوقف الاستعلام بمجرد انتهاء النطاق.
* تُخرَج كتل البيانات أثناء معالجتها إلى أن يبدأ التنفيذ الخارجي.

## DISTINCT في الذاكرة الخارجية

يمكن لـ `DISTINCT` كتابة بيانات مؤقتة على القرص لمعالجة مجموعات من القيم المميزة التي يتعذّر
الاحتفاظ بها في الذاكرة لكبر حجمها. ويتطلب ذلك عمليات إدخال/إخراج إضافية على القرص، وقد يبطئ الاستعلامات.

ويتحكم إعدادان في وقت بدء الكتابة على القرص:

* `max_bytes_before_external_distinct` يحدد عتبة بالبايت من إجمالي ذاكرة الاستعلام. وقيمته الافتراضية
  `0` (معطّل).
* `max_bytes_ratio_before_external_distinct` يحدد نسبة من الذاكرة المتاحة ضمن حدود الخادم أو
  المستخدم، تُقاس عند بدء التنفيذ. وقيمته الافتراضية `0.5`، ولا يكون له أي تأثير إذا
  لم ينطبق أي من الحدّين.

وعند انطباق العتبتين معًا، تُستخدم الأصغر. اضبط كلا الإعدادين على `0` لتعطيل الكتابة على القرص.

ولا يؤثر `max_memory_usage` في النسبة. ولتهيئة الكتابة على القرص نسبةً إلى حد ذاكرة الاستعلام،
اضبط عتبة مطلقة أقل من ذلك الحد. على سبيل المثال، يستخدم هذا الاستعلام عتبة كتابة على القرص مقدارها 16 ميبي بايت
مع حد ذاكرة استعلام يبلغ 256 ميبي بايت:

```sql theme={null}
SELECT DISTINCT number % 1000000 AS id
FROM numbers(2000000)
SETTINGS
    max_bytes_before_external_distinct = 16777216,
    max_bytes_ratio_before_external_distinct = 0,
    max_memory_usage = 268435456;
```

لا تضع هذه العتبات حدًا أقصى لاستهلاك الذاكرة. اترك مساحة لبقية عمليات معالجة الاستعلام وللكتابة إلى القرص
نفسها. كما قد تبدأ الكتابة إلى القرص في وقت أبكر عند وجود ضغط على الذاكرة.

يمكن إرجاع الصفوف قبل بدء الكتابة إلى القرص، وإذا تحقق شرط `LIMIT` في هذه المرحلة فقد ينتهي الاستعلام مبكرًا.
وبمجرد بدء الكتابة إلى القرص، يجب قراءة بقية المدخلات قبل التمكّن من إرجاع النتائج المتبقية.
وإذا تضمّن الاستعلام `ORDER BY`، فسترد تلك النتائج بالترتيب المطلوب.

عندما يستخدم `DISTINCT` مدخلات مرتّبة وفق بادئة من مفاتيحه، فإنه لا يكتب إلى القرص. ومع ذلك، قد تستهلك مجموعة كبيرة من الصفوف
التي تشترك في البادئة نفسها قدرًا كبيرًا من الذاكرة.

وكما هو الحال مع `optimize_distinct_in_order`، قد تؤدي الكتابة إلى القرص إلى إزالة تكرار القيم ذات الفاصلة العائمة التي تختلف
تمثيلاتها الثنائية لكنها متساوية عند المقارنة، بما في ذلك `0.0` و`-0.0`، أو قيم `NaN`
ذات حمولات مختلفة.
