المجاميع التراكمية باستخدام إطارات النوافذ
إنشاء مجموع جارٍ باستخدام SUM OVER مع إطار مرتب
المجاميع التراكمية باستخدام إطارات النوافذ درس مجاني في Coding Interview Prep على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Coding Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Coding Interview Prep 4 دروس في المجموع.
سؤال الإجمالي التراكمي
تتضمن تقريبًا كل مقابلة لمحللي البيانات سؤالًا من نوع: «اعرض لي الإيرادات التراكمية بمرور الوقت». الإجمالي التراكمي هو مجموع ينمو صفًا بعد صف، فيراكم كل شيء من البداية حتى الصف الحالي.
قبل ظهور دوال النوافذ، كان المترشحون يحلون ذلك باستخدام ربط ذاتي بطيء أو استعلام فرعي مترابط. أما الإجابة الحديثة المتوقعة فهي SUM(...) OVER (ORDER BY ...). ومعرفة صيغة إطار النافذة تشير إلى أنك تفهم SQL المكتوب بعد نحو عام 2012.
بنية مجموع نافذة مرتبة
الإجمالي التراكمي ليس سوى دالة تجميع تحولت إلى دالة نافذة. تحتفظ بـ SUM(amount)، لكنك تضيف عبارة OVER تتضمن ORDER BY.
إن ORDER BY داخل OVER هو ما يجعل الناتج تراكميًا؛ فهو يخبر SQL بتجميع الصفوف بهذا الترتيب. ومن دون ORDER BY، سيحسب SUM إجمالي التقسيم بأكمله لكل صف بدلًا من أن ينمو تدريجيًا.
SELECT
sale_date,
amount,
SUM(amount) OVER (ORDER BY sale_date) AS running_total
FROM sales
ORDER BY sale_date;لماذا يحدد ORDER BY إطارًا
إليك التفصيل الذي يحب المحاورون التحقق منه: عند إضافة ORDER BY إلى دالة تجميع نافذة، يطبّق SQL إطارًا افتراضيًا هو RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.
وهذا الإطار الافتراضي هو بالضبط ما ينتج الإجمالي التراكمي: كل صف من بداية التقسيم حتى الصف الحالي، بما في ذلك الصف الحالي. إذا فهمت هذا الإطار الافتراضي، فقد فهمت سبب عمل المجموع التراكمي «تلقائيًا».
جعل الإطار صريحًا
يمكنك كتابة الإطار يدويًا. يعيد هذان الاستعلامان النتيجة نفسها، لكن النسخة الصريحة تُظهر للمحاور أنك تعرف ما يحدث داخل SQL.
تُعد كتابة ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW الصيغة الصريحة الأكثر أمانًا للإجمالي التراكمي، لأنها تحسب الصفوف الفعلية وتتجنب مفاجآت تجميع القيم في RANGE، التي يتناولها الدرس التالي.
SELECT
sale_date,
amount,
SUM(amount) OVER (
ORDER BY sale_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total
FROM sales;مثال تطبيقي: المبيعات اليومية
لنتخيل مبيعات أربعة أيام: الإثنين 100، والثلاثاء 50، والأربعاء 200، والخميس 75. يتراكم الإجمالي من اليسار إلى اليمين.
- الإثنين: 100
- الثلاثاء: 100 + 50 = 150
- الأربعاء: 150 + 200 = 350
- الخميس: 350 + 75 = 425
يساوي الصف الأخير دائمًا الإجمالي الكلي. وهذه طريقة سريعة للتحقق من صحة النتيجة يمكنك ذكرها في المقابلة: يجب أن تتطابق آخر قيمة في الإجمالي التراكمي مع SUM(amount) على المجموعة بأكملها.
إعادة الضبط لكل مجموعة باستخدام PARTITION BY
تريد الأسئلة الواقعية عادةً إجماليًا تراكميًا لكل عميل أو لكل منطقة، لا إجماليًا عالميًا واحدًا. أضف PARTITION BY، فتبدأ عملية التراكم من جديد عند بداية كل تقسيم.
النموذج الذهني هو الآتي: يقسم PARTITION BY الصفوف إلى مجموعات مستقلة، ثم يعمل كل من ORDER BY والإطار بصورة منفصلة داخل كل مجموعة.
SELECT
customer_id,
sale_date,
amount,
SUM(amount) OVER (
PARTITION BY customer_id
ORDER BY sale_date
) AS customer_running_total
FROM sales;فخ كاسر التعادل
إذا اشترك صفان في قيمة ORDER BY نفسها، مثل مبيعتين في التاريخ نفسه، فإن إطار RANGE الافتراضي يعاملهما باعتبارهما صفين متساويين، ويمنحهما الإجمالي التراكمي نفسه، بما في ذلك مبلغا المعاملتين.
إذا احتجت إلى زيادة صارمة صفًا بعد صف حتى عند التعادل، فانتقل إلى استخدام إطار ROWS وأضف كاسر تعادل فريدًا إلى ORDER BY، مثل sale_date, id. يضع المحاورون تواريخ مكررة عمدًا ليروا ما إذا كنت ستلاحظ ذلك.
SELECT
sale_date,
amount,
SUM(amount) OVER (
ORDER BY sale_date, id
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total
FROM sales;الإجمالي التراكمي لعدد
لا يقتصر المنطق التراكمي على SUM. فأي دالة تجميع يمكن استخدامها كدالة نافذة، ولذلك يمكنك إنشاء عدد تراكمي، أو متوسط تراكمي، أو قيمة عظمى تراكمية.
يُعد العدد التراكمي للطلبات مقياسًا شائعًا في لوحات المعلومات: كم عدد الطلبات التي تلقيناها حتى الآن في كل يوم؟
SELECT
order_date,
COUNT(*) OVER (
ORDER BY order_date
) AS orders_to_date
FROM orders;الطريقة القديمة: استعلام فرعي مترابط
يطلب منك المحاورون أحيانًا حل مسألة الإجمالي التراكمي من دون استخدام دوال النوافذ لاختبار مدى عمق فهمك. والحل التقليدي السابق لظهور النوافذ هو استعلام فرعي مترابط يعيد جمع كل صف سابق.
يعمل هذا الحل، لكنه ذو تعقيد O(n²)، لأنه يعيد مسح الجدول لكل صف. اذكر ذلك لتُظهر أنك تعرف سبب استبدال دوال النوافذ له.
SELECT
s.sale_date,
s.amount,
(SELECT SUM(s2.amount)
FROM sales s2
WHERE s2.sale_date <= s.sale_date) AS running_total
FROM sales s
ORDER BY s.sale_date;التصفية مقابل نتيجة النافذة
من الأسئلة اللاحقة الشائعة: «اعرض الأيام التي تجاوز فيها الإجمالي التراكمي 1000 فقط». لا يمكنك وضع دالة نافذة في WHERE، لأن الإطار يُحسب بعد تنفيذ WHERE.
الحل هو حساب الإجمالي التراكمي في CTE أو استعلام فرعي، ثم تطبيق التصفية في الاستعلام الخارجي. وهذه هي قاعدة الإحاطة نفسها التي تنطبق على كل دالة نافذة.
WITH t AS (
SELECT
sale_date,
SUM(amount) OVER (ORDER BY sale_date) AS running_total
FROM sales
)
SELECT *
FROM t
WHERE running_total >= 1000;نقاط مهمة للمقابلة
عند تقديم إجابة عن الإجمالي التراكمي، اشرح هذه النقاط لتحصل على التقييم الكامل:
- تمثل
SUM OVER (ORDER BY ...)الصيغة التراكمية. - تؤدي إضافة
ORDER BYإلى إنشاء إطار افتراضي منUNBOUNDED PRECEDINGإلىCURRENT ROW. - استخدم
PARTITION BYلإعادة الضبط لكل مجموعة. - أضف كاسر تعادل فريدًا واستخدم إطار
ROWSلتجنب مشكلة القيم المكررة. - أحط الاستعلام داخل CTE لتطبيق التصفية على النتيجة.
تحقق سريع
اختبر فهمك للإطار الافتراضي.
خلاصة: المجاميع التراكمية
الإجمالي التراكمي هو دالة تجميع مرتبة ضمن نافذة. يجمع SUM(amount) OVER (ORDER BY sale_date) الصفوف من بداية التقسيم حتى الصف الحالي، بفضل إطار UNBOUNDED PRECEDING إلى CURRENT ROW المطبق ضمنيًا.
أعد ضبطه لكل مجموعة باستخدام PARTITION BY، وأضف كاسر تعادل مع إطار ROWS للتعامل مع قيم الفرز المكررة، وأحطه داخل CTE كلما احتجت إلى تطبيق التصفية على القيمة التراكمية. بعد ذلك سنفكك الفرق بين ROWS وRANGE الذي أشار إليه هذا الدرس.
الأسئلة الشائعة
هل درس «المجاميع التراكمية باستخدام إطارات النوافذ» مجاني؟
نعم — نص درس «المجاميع التراكمية باستخدام إطارات النوافذ» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Coding Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة Coding Interview Prep 4 دروس في المجموع.
ماذا ستتعلم في «المجاميع التراكمية باستخدام إطارات النوافذ»؟
إنشاء مجموع جارٍ باستخدام SUM OVER مع إطار مرتب تتمرن على Coding Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Coding Interview Prep؟
لا تُشترط خبرة سابقة. Coding Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «المجاميع التراكمية باستخدام إطارات النوافذ»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Coding Interview Prep هذا؟
نعم. كل درس في Coding Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- المجاميع التراكمية باستخدام إطارات النوافذ
- تأطير ROWS مقابل RANGE
- المتوسطات المتحركة عبر نافذة منزلقة
- التوزيع التراكمي والنسبة من الإجمالي