تأطير ROWS مقابل RANGE
الفرق الدقيق والمختبر بكثرة بين الإطارات القائمة على الصفوف والقيم
تأطير ROWS مقابل RANGE درس مجاني في SQL Interview Prep على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.
الفرق الذي يختبره المحاورون
بعد أن تتمكن من كتابة إجمالي تراكمي، يأتي السؤال اللاحق الطبيعي: «ما الفرق بين ROWS وRANGE في إطار النافذة؟» وهذا مؤشر دقيق على مستوى متوسط. فكثير من المترشحين يستخدمون الإطارات يوميًا من دون أن يلاحظوا أن الكلمتين تتصرفان بطريقة مختلفة.
يحدد كلاهما مجموعة الصفوف التي تراها دالة التجميع، لكنهما يحسبان تلك المجموعة بطريقتين مختلفتين جوهريًا. أتقن هذه النقطة وستتميز عن غيرك.
يحسب ROWS الصفوف الفعلية
يعمل ROWS بطريقة موضعية. ويعني ROWS BETWEEN 2 PRECEDING AND CURRENT ROW حرفيًا الصف الحالي مضافًا إليه الصفان الفعليان الموجودان فوقه مباشرةً في التسلسل المرتب.
ولا يهتم بما إذا كانت الصفوف المجاورة تشترك في قيمة ORDER BY نفسها. ثلاثة صفوف تعني ثلاثة صفوف، لا أكثر ولا أقل. وهذا هو الإطار الذي تريده غالبًا للمتوسطات المتحركة والمجاميع التراكمية الصارمة.
SELECT
sale_date,
amount,
SUM(amount) OVER (
ORDER BY sale_date
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS rows_sum
FROM sales;يحسب RANGE حسب القيمة
يعمل RANGE بطريقة قائمة على القيمة. فهو يتضمن كل صف تقع قيمة ORDER BY الخاصة به ضمن نطاق منطقي لقيمة الصف الحالي، وليس عددًا معينًا من الصفوف.
والنتيجة الأهم هي أنه مع RANGE تُعامل كل الصفوف المتعادلة في قيمة ORDER BY باعتبارها مجموعة واحدة من الصفوف المتساوية. وتحصل جميعها على الإطار نفسه، وبالتالي على النتيجة نفسها.
SELECT
sale_date,
amount,
SUM(amount) OVER (
ORDER BY sale_date
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS range_sum
FROM sales;مثال التعادل الذي يكشف الفرق
لنفترض أن مبيعتين حدثتا في 2024-03-02، بمبلغين قدرهما 30 و40، وسبقتهما مبيعة في 2024-03-01 بمبلغ 100.
- مع RANGE حتى CURRENT ROW: يُعد صفا 03-02 متساويين، ولذلك يعرض كلاهما 100 + 30 + 40 = 170.
- مع ROWS حتى CURRENT ROW: يعرض صف 03-02 الأول القيمة 130، بينما يعرض الصف الثاني 170، لأن كل صف يوسّع الإطار موضعًا واحدًا في كل مرة.
البيانات نفسها، لكن الأرقام مختلفة. وهذا الاختلاف عند وجود التعادل هو جوهر السؤال.
لماذا يكون الافتراضي RANGE
تذكّر أن OVER (ORDER BY ...) من دون إطار صريح يستخدم افتراضيًا RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.
وهذا يعني أن الإجمالي التراكمي البسيط يستخدم RANGE بصمت. ومع مفاتيح الفرز الفريدة يكون مطابقًا لـ ROWS، ولذلك يظل الخطأ مخفيًا. لكن ما إن تظهر قيم فرز مكررة حتى يجمع إجماليُك التراكمي الصفوف المتعادلة معًا دون تنبيه. ولهذا يكتب المهندسون ذوو الخبرة ROWS صراحةً.
RANGE مع إزاحات رقمية
يمكن أن تتلقى RANGE إزاحة قيمية، وليس UNBOUNDED فقط. ويشمل RANGE BETWEEN 7 PRECEDING AND CURRENT ROW، عند تطبيقه على عمود تاريخ أو عمود رقمي، كل صف تكون قيمته ضمن 7 وحدات من قيمة الصف الحالي.
عند تطبيقه على تاريخ، ينتج عن ذلك نافذة حقيقية لـ "آخر 7 أيام" تتجاوز الأيام المفقودة بشكل صحيح، بينما يجلب ROWS 7 PRECEDING الصفوف السابقة السبعة بغض النظر عن الفجوات. إن معرفة هذا التفصيل تُعد إجابة قوية.
SELECT
sale_date,
amount,
SUM(amount) OVER (
ORDER BY sale_date
RANGE BETWEEN INTERVAL '7 days' PRECEDING AND CURRENT ROW
) AS last_7_days
FROM sales;ROWS يتجاهل الفجوات
أما الجانب المقابل فهو أن ROWS لا يتعامل مع الفجوات في البيانات. فإذا كان جدول المبيعات لا يتضمن عطلات نهاية الأسبوع، فإن ROWS BETWEEN 6 PRECEDING AND CURRENT ROW يمتد عبر 7 أيام مسجلة، وقد يغطي فعليًا أسبوعين تقويميين.
لذلك يعتمد الاختيار على المقصود: آخر N سجلات يعني استخدام ROWS؛ أما آخر N وحدة من القيمة (أيام أو دولارات) فيعني استخدام RANGE مع إزاحة.
مراجعة واقعية لدعم لهجات SQL
تتضمن الإجابة الصادقة في مقابلة العمل الإشارة إلى تفاوت الدعم:
- يدعم PostgreSQL استخدام
RANGEمع الإزاحات (منذ الإصدار 11)، كما يدعمROWSبالكامل. - يدعم SQL Server كلًا من
ROWSوRANGE، لكنRANGEيقتصر علىUNBOUNDED/CURRENT ROWولا يدعم الإزاحات الرقمية. - يدعم MySQL 8 كليهما، مع أنواع محدودة من إزاحات
RANGE.
إذا لم تتوفر إزاحة رقمية لـ RANGE، فيمكن محاكاتها باستخدام ربط ذاتي أو تقويم مُنشأ. وذكر ذلك يوضح وعيك بمتطلبات بيئات الإنتاج.
GROUPS: النمط الثالث
هناك نمط ثالث أقل شهرة لتحديد الإطار، وهو GROUPS. فهو يعدّ مجموعات القيم المتساوية بدلًا من الصفوف أو القيم. ويشمل GROUPS BETWEEN 1 PRECEDING AND CURRENT ROW مجموعة القيم المتساوية الحالية والمجموعة التي تسبقها.
قلّما يُطلب هذا النمط، لكن ذكره عند السؤال "هل توجد أنماط إطارات أخرى؟" يثبت امتلاكك معرفة عميقة فعلية. ويتوفر دعمه في PostgreSQL 11+ وبعض الأنظمة الأخرى.
SELECT
sale_date,
amount,
SUM(amount) OVER (
ORDER BY sale_date
GROUPS BETWEEN 1 PRECEDING AND CURRENT ROW
) AS two_day_groups
FROM sales;قاعدة قرار يمكنك ترديدها
اختصر الموضوع بأكمله في جملة واحدة يمكنك قولها في مقابلة العمل:
"استخدم ROWS عندما أقصد عددًا ثابتًا من الصفوف الفعلية، واستخدم RANGE عندما أقصد نطاقًا منطقيًا من قيمة الترتيب، وتذكّر أن القيم المتساوية تجعلهما يختلفان لأن RANGE الافتراضي يجمع القيم المتساوية معًا."
تجيب هذه الجملة الواحدة عن السؤال كاملًا وبثقة.
مقارنة جنبًا إلى جنب
يُظهر وضع الإطارين في استعلام واحد موضع الاختلاف بوضوح. شغّل هذا الاستعلام على بيانات تحتوي على تواريخ مكررة، وقارن العمودين صفًا بصف.
في التواريخ الفريدة يتطابق العمودان تمامًا؛ أما في التواريخ المتساوية، فيكرر عمود RANGE الإجمالي نفسه عبر القيم المتساوية، بينما يرتفع عمود ROWS خطوة واحدة في كل مرة.
SELECT
sale_date,
amount,
SUM(amount) OVER (ORDER BY sale_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS rows_total,
SUM(amount) OVER (ORDER BY sale_date
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS range_total
FROM sales;تحقق سريع
يتساوى صفان في قيمة ORDER BY مع استخدام إطار افتراضي. ماذا يحدث؟
مراجعة: ROWS مقابل RANGE
يعدّ ROWS الصفوف الفعلية؛ بينما يعدّ RANGE وفق القيمة المنطقية لعمود الترتيب، ويجمع القيم المتساوية باعتبارها قيمًا متساوية. وإطار OVER (ORDER BY ...) الافتراضي هو RANGE، ولذلك قد يجمع الإجمالي التراكمي الساذج قيم الترتيب المكررة معًا.
اختر ROWS لـ "آخر N سجلًا" وللنوافذ المتحركة التي لا تتأثر بالفجوات؛ واختر RANGE مع إزاحة لـ "آخر N يومًا/دولارًا" عندما تريد مراعاة الفجوات. ومعرفة وجود GROUPS تُعد ميزة إضافية. بعد ذلك سنطبق تأطير ROWS لإنشاء متوسطات متحركة.
الأسئلة الشائعة
هل درس «تأطير ROWS مقابل RANGE» مجاني؟
نعم — نص درس «تأطير ROWS مقابل RANGE» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.
ماذا ستتعلم في «تأطير ROWS مقابل RANGE»؟
الفرق الدقيق والمختبر بكثرة بين الإطارات القائمة على الصفوف والقيم تتمرن على SQL Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ SQL Interview Prep؟
لا تُشترط خبرة سابقة. SQL Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «تأطير ROWS مقابل RANGE»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس SQL Interview Prep هذا؟
نعم. كل درس في SQL Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- المجاميع التراكمية باستخدام إطارات النوافذ
- تأطير ROWS مقابل RANGE
- المتوسطات المتحركة عبر نافذة منزلقة
- التوزيع التراكمي والنسبة من الإجمالي