دوال النافذة القياسية
| الميزة | مدعومة؟ | تعليق |
|---|---|---|
تحديد نافذة مخصص (count(*) OVER (PARTITION BY id ORDER BY time DESC)) | ✅ | |
تعبيرات تتضمن دوال النافذة، مثل (count(*) OVER ()) / 2 | ✅ | |
عبارة WINDOW (SELECT ... FROM table WINDOW w AS (PARTITION BY id)) | ✅ | |
إطار ROWS | ✅ | |
إطار RANGE | ✅ | يُستخدم افتراضيًا عندما لا يُحدَّد إطار بشكل صريح (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW). |
صياغة INTERVAL لإطار DateTime RANGE OFFSET | ❌ | حدِّد عدد الثواني بدلًا من ذلك (RANGE يعمل مع أي نوع رقمي). |
إطار GROUPS | ❌ | |
حساب الدوال التجميعية على إطار (sum(value) OVER (ORDER BY time)) | ✅ | جميع الدوال التجميعية مدعومة. |
rank(), dense_rank()/denseRank(), row_number() | ✅ | |
percent_rank()/percentRank() | ✅ | يحسب بكفاءة الترتيب النسبي لقيمة داخل قسم. ويستبدل بذلك حساب SQL يدويًا أطول وأكثر كلفةً من ناحية المعالجة، والمعبَّر عنه كما يلي: ifNull((rank() OVER (PARTITION BY x ORDER BY y) - 1) / nullif(count(1) OVER (PARTITION BY x) - 1, 0), 0). |
cume_dist() | ✅ | يحسب التوزيع التراكمي لقيمة داخل مجموعة من القيم. ويُرجع النسبة المئوية للصفوف التي تكون قيمها أقل من قيمة الصف الحالي أو مساوية لها. |
lag/lead(value, offset) | ✅ | يمكنك أيضًا استخدام أحد الحلول البديلة التالية: 1) any(value) OVER (... ROWS BETWEEN <offset> PRECEDING AND <offset> PRECEDING)، أو FOLLOWING بدلًا من PRECEDING في حالة lead 2) lagInFrame/leadInFrame، وهما متشابهان لكنهما يراعيان إطار النافذة. للحصول على سلوك مطابق تمامًا لـ lag/lead، استخدم ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING. |
ntile(buckets) | ✅ | حدِّد النافذة، على سبيل المثال، على النحو التالي: (PARTITION BY x ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING). |
الصيغة
PARTITION BY- يحدّد كيفية تقسيم مجموعة النتائج إلى مجموعات.ORDER BY- يحدّد كيفية ترتيب الصفوف داخل المجموعة أثناء حساب aggregate_function.ROWS or RANGE- يحدّد حدود الإطار، ويُحسَب aggregate_function ضمن هذا الإطار.WINDOW- يتيح لعدة تعبيرات استخدام تعريف النافذة نفسه.
الدوال التي لا يمكن استخدامها إلا كدوال نافذة
lagInFrame وleadInFrame وnonNegativeDerivative امتدادات خاصة بـ ClickHouse.
| Function | Description |
|---|---|
row_number() | رقِّم الصف الحالي داخل القسم الخاص به بدءًا من 1. |
first_value(x) | أرجِع أول قيمة جرى تقييمها ضمن الإطار المرتَّب. |
last_value(x) | أرجِع آخر قيمة جرى تقييمها ضمن الإطار المرتَّب. |
nth_value(x, offset) | أرجِع أول قيمة non-NULL جرى تقييمها عند الصف رقم n (offset) ضمن الإطار المرتَّب. |
rank() | امنح الصف الحالي ترتيبًا داخل القسم الخاص به مع وجود فجوات. |
dense_rank() | امنح الصف الحالي ترتيبًا داخل القسم الخاص به من دون فجوات. |
lagInFrame(x) | أرجِع قيمة جرى تقييمها عند صف يسبق الصف الحالي بإزاحة مادية محددة ضمن الإطار المرتَّب. |
leadInFrame(x) | أرجِع قيمة جرى تقييمها عند صف يلي الصف الحالي بعدد صفوف الإزاحة ضمن الإطار المرتَّب. |
nonNegativeDerivative(metric_column, timestamp_column[, INTERVAL X UNITS]) | احسب المشتقة غير السالبة لـ metric_column بالنسبة إلى timestamp_column. هذه الدالة خاصة بـ ClickHouse. |
أمثلة
ترقيم الصفوف
دوال التجميع
التقسيم حسب العمود
تعيين حدود الإطار
أمثلة واقعية
الحد الأقصى/إجمالي الرواتب لكل قسم
المجموع التراكمي
المتوسط المتحرك / المتوسط الانزلاقي (لكل 3 صفوف)
المتوسط المتحرك / المتوسط الانزلاقي (كل 10 ثوانٍ)
المتوسط المتحرك / المتوسط الانزلاقي (لكل 10 أيام)
Range و ORDER BY toDate(ts) نُكوِّن إطارًا بحجم 10 وحدات، وبما أن toDate(ts) مستخدَمة هنا، فالوحدة هي اليوم.