Coding Interview Prep · درس

OVER وPARTITION BY وORDER BY

تشريح مواصفة النافذة وكيف تعيد الأقسام ضبط الحساب

الدرس 1 من 413 خطوة

OVER وPARTITION BY وORDER BY درس مجاني في Coding Interview Prep على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Coding Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Coding Interview Prep 4 دروس في المجموع.

لماذا يلجأ المحاورون إلى دوال النافذة

تُجري دالة النافذة عملية حسابية على مجموعة من الصفوف المرتبطة بالصف الحالي، من دون دمجها كما يفعل GROUP BY. وهذه الخاصية وحدها هي سبب حب المحاورين لها: إذ تحتفظ بكل صف تفصيلي، وتحصل في الوقت نفسه على قيمة تجميعية أو ترتيب أو مجموع تراكمي إلى جانبه.

  • GROUP BY يُرجع صفًا واحدًا لكل مجموعة.
  • دالة نافذة تُرجع كل صف من صفوف الإدخال مع عمود محسوب إضافي.

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

بنية عبارة OVER

تتبع كل دالة نافذة عبارة OVER (...). وتتكون العبارة من ثلاثة أجزاء اختيارية، وتثير دقة تسميتها إعجاب المحاورين:

  • PARTITION BY — يقسم الصفوف إلى مجموعات، وتُعاد الدالة في كل مجموعة.
  • ORDER BY — يرتب الصفوف داخل كل مجموعة، وهو مطلوب للترتيب والمجاميع التراكمية.
  • الإطار — يحدد الصفوف التي تدخل في العملية الحسابية، مثل ROWS/RANGE.

يتعامل OVER () الفارغ مع مجموعة النتائج بأكملها باعتبارها مجموعة واحدة.

SELECT
  name,
  department,
  salary,
  AVG(salary) OVER (PARTITION BY department) AS dept_avg
FROM employees;

دالة النافذة في مقابل التجميع: الدالة نفسها والنتيجة مختلفة

تتصرف دالة التجميع نفسها بطريقة مختلفة تمامًا عند استخدامها كدالة نافذة. قارن بين الاستعلامين التاليين من الناحية المفاهيمية.

  • يُرجع AVG(salary) مع GROUP BY department صفًا واحدًا لكل قسم.
  • يُرجع AVG(salary) OVER (PARTITION BY department) كل موظف، مع إرفاق متوسط راتب القسم بكل موظف.

نصيحة للمقابلة: أكّد أن إصدار النافذة لا يتطلب GROUP BY ولا يزيل صفوف التفاصيل المكررة.

-- Aggregate: collapses
SELECT department, AVG(salary)
FROM employees
GROUP BY department;

-- Window: preserves every row
SELECT department, name, AVG(salary) OVER (PARTITION BY department) AS dept_avg
FROM employees;

PARTITION BY: إعادة ضبط الحساب

بالنسبة إلى دوال النوافذ، تؤدي PARTITION BY الدور نفسه الذي تؤديه GROUP BY بالنسبة إلى الدوال التجميعية، لكنها لا تدمج الصفوف. يحصل كل قسم ذي قيمة مميزة على حساب مستقل خاص به.

في المثال، يبدأ رقم الصف من 1 من جديد لكل قسم. ومن دون PARTITION BY، سيستمر الترقيم عبر جميع الموظفين.

  • يمكنك التقسيم حسب عمود واحد أو عدة أعمدة.
  • يعني غياب PARTITION BY وجود قسم واحد ضخم (مجموعة البيانات بأكملها).
SELECT
  department,
  name,
  ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn
FROM employees;

ORDER BY داخل OVER

إن ORDER BY الموجود داخل OVER ليس هو نفسه ORDER BY النهائي للاستعلام. فهو يحدد فقط تسلسل الصفوف داخل كل قسم الذي تعمل عليه الدالة.

  • تتطلبه دوال الترتيب (ROW_NUMBER وRANK) — فهي تحتاج إلى ترتيب تستند إليه.
  • لا تحتاج الدوال التجميعية العادية ضمن قسم إلى ذلك، إلا إذا كنتم تريدون حسابًا تراكميًا.

من الأخطاء الشائعة في المقابلات الخلط بين ORDER BY الخاص بالنافذة وترتيب عرض المخرجات.

SELECT
  name,
  hire_date,
  ROW_NUMBER() OVER (ORDER BY hire_date) AS seniority_rank
FROM employees
ORDER BY name;  -- output order is independent of the window order

الجمع بين PARTITION BY وORDER BY

تجمع نافذة الترتيب الكلاسيكية بين الاثنين: تعمل PARTITION BY على التجميع، ثم يحدد ORDER BY التسلسل داخل كل مجموعة.

اقرأ المواصفة أدناه على النحو التالي: «داخل كل قسم، رتّب الموظفين حسب الراتب تنازليًا، ورقّمهم». يحصل صاحب أعلى راتب في كل قسم على رقم الصف 1.

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

SELECT
  department,
  name,
  salary,
  ROW_NUMBER() OVER (
    PARTITION BY department
    ORDER BY salary DESC
  ) AS dept_salary_rank
FROM employees;

يغيّر ORDER BY سلوك الدوال التجميعية

إليك نقطة دقيقة يختبرها المحاورون: إن إضافة ORDER BY إلى نافذة تجميعية تحولها إلى حساب تراكمي، لأن إطارًا ضمنيًا («من بداية القسم حتى الصف الحالي») يبدأ تطبيقه.

  • SUM(x) OVER (PARTITION BY g) → إجمالي المجموعة نفسه في كل صف.
  • SUM(x) OVER (PARTITION BY g ORDER BY d) → إجمالي تراكمي حتى الصف الحالي.

إن معرفة أن ORDER BY يضيف إطارًا ضمنيًا تميّز بين المرشحين ذوي المستوى المتوسط والمبتدئين.

SELECT
  account_id,
  txn_date,
  amount,
  SUM(amount) OVER (
    PARTITION BY account_id
    ORDER BY txn_date
  ) AS running_balance
FROM transactions;

أين يُسمح باستخدام دوال النوافذ

لا يمكن أن تظهر دوال النوافذ إلا في قائمة SELECT وبند ORDER BY. وهي غير مسموح بها في WHERE أو GROUP BY أو HAVING.

يرتبط السبب بترتيب التنفيذ المنطقي: تُقيَّم دوال النوافذ بعد تنفيذ WHERE وGROUP BY وHAVING. وتكون الصفوف قد اختيرت بالفعل قبل أن تراها النافذة.

لهذا يتطلب التصفية حسب الترتيب استعلامًا فرعيًا أو CTE — وهي نقطة ستُشرح بالكامل في درس لاحق.

-- This FAILS: window function in WHERE
-- SELECT name FROM employees
-- WHERE ROW_NUMBER() OVER (ORDER BY salary) = 1;

-- This works: window in SELECT, filter outside
SELECT * FROM (
  SELECT name, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn
  FROM employees
) t
WHERE rn = 1;

دوال نوافذ متعددة في استعلام واحد

يمكنك استخدام عدة دوال نوافذ في SELECT نفسه، ولكل منها مواصفة خاصة بها أو مواصفة مشتركة. تحسب قاعدة البيانات هذه الدوال في مرور واحد على البيانات المقسمة.

يفيد هذا في المقابلات عندما تحتاجون إلى الترتيب ومتوسط القسم معًا. وإذا اشتركت دالتان في مواصفة، تسمح بعض لهجات SQL بتسميتها باستخدام بند WINDOW لتجنب التكرار.

SELECT
  name,
  department,
  salary,
  ROW_NUMBER() OVER w  AS rn,
  AVG(salary) OVER (PARTITION BY department) AS dept_avg
FROM employees
WINDOW w AS (PARTITION BY department ORDER BY salary DESC);

مثال محلول: الراتب مقارنة بمتوسط القسم

سؤال شائع للمحللين: «اعرض كل موظف مع راتبه ومتوسط قسمه والفرق بينهما». يتولى تعبير نافذة واحد الجزء الأكبر من العمل، وتتولى العمليات الحسابية الباقي.

لاحظ عدم وجود GROUP BY وبقاء صف كل موظف. يتكرر dept_avg لدى جميع الموظفين في القسم نفسه، وهذا بالضبط ما يجعل المقارنة ممكنة صفًا بصف.

SELECT
  name,
  department,
  salary,
  AVG(salary) OVER (PARTITION BY department) AS dept_avg,
  salary - AVG(salary) OVER (PARTITION BY department) AS diff_from_avg
FROM employees
ORDER BY department, salary DESC;

الأخطاء الشائعة التي ينتبه إليها المحاورون

تجنب هذه المطبات عند طرح دوال النوافذ:

  • وضع دالة نافذة في WHERE أو HAVING — غير مسموح؛ استخدم استعلامًا فرعيًا.
  • نسيان ORDER BY في دالة ترتيب — فتصبح النتائج عشوائية.
  • افتراض أن PARTITION BY يقلل عدد الصفوف — فهو لا يفعل ذلك مطلقًا.
  • الخلط بين ORDER BY الخاص بالنافذة وترتيب المخرجات النهائي.
  • إضافة ORDER BY إلى نافذة تجميعية وعدم إدراك أنها تحولت إلى إجمالي تراكمي.

تحقق سريع

اختبر مدى استيعابك لمواصفة النافذة.

مراجعة: مواصفة النافذة

أصبحت الآن متمكنًا من بنية OVER (...):

  • تحافظ دوال النوافذ على كل صف، مع إجراء الحساب عبر الصفوف المرتبطة.
  • تجمع PARTITION BY الصفوف وتعيد ضبط الحساب؛ ولا تحذف الصفوف مطلقًا.
  • يرتّب ORDER BY الصفوف داخل القسم؛ وتتطلبه دوال الترتيب، كما أنه يحوّل الدوال التجميعية إلى حسابات تراكمية.
  • لا يُسمح بدوال النوافذ إلا في SELECT وORDER BY — وليس في WHERE/HAVING مطلقًا.

بعد ذلك، ستسند أرقامًا تسلسلية حتمية باستخدام ROW_NUMBER.

البدء مجانًا

تعلم Coding Interview Prep مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
90
الدروس
360

الأسئلة الشائعة

هل درس «OVER وPARTITION BY وORDER BY» مجاني؟

نعم — نص درس «OVER وPARTITION BY وORDER BY» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Coding Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة Coding Interview Prep 4 دروس في المجموع.

ماذا ستتعلم في «OVER وPARTITION BY وORDER BY»؟

تشريح مواصفة النافذة وكيف تعيد الأقسام ضبط الحساب تتمرن على Coding Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Coding Interview Prep؟

لا تُشترط خبرة سابقة. Coding Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «OVER وPARTITION BY وORDER BY»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Coding Interview Prep هذا؟

نعم. كل درس في Coding Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. OVER وPARTITION BY وORDER BY
  2. ROW_NUMBER للتسلسل الفريد
  3. RANK مقابل DENSE_RANK عند التعادل
  4. التصفية حسب نتيجة دالة نافذة
← العودة إلى Coding Interview Prep