0Pricing
Coding Interview Prep · درس

التغير من فترة إلى أخرى

حساب النمو من شهر إلى شهر والفروق من يوم إلى يوم باستخدام LAG

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

السؤال المؤكد لمحلل البيانات

إذا تقدمت لمقابلة لوظيفة محلل بيانات، فتوقع سؤالًا مثل: «احسب النمو من شهر إلى آخر» أو «ما التغير من يوم إلى آخر؟» فهذا السؤال يكاد يكون حتميًا.

اللبنة الأساسية هي LAG: استخرج قيمة الفترة السابقة، ثم احسب فرقًا مطلقًا أو تغيرًا نسبيًا. يحوّل هذا الدرس LAG إلى أنماط للتغير من فترة إلى أخرى يقيّمك القائمون بالمقابلات بناءً عليها.

التغير المطلق باستخدام LAG

أبسط صيغة هي الفرق الخام بين الفترة الحالية والفترة السابقة. استخرج القيمة السابقة باستخدام LAG، ثم اطرحها مباشرةً.

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

SELECT
  month,
  revenue,
  revenue - LAG(revenue) OVER (ORDER BY month) AS mom_change
FROM monthly_sales
ORDER BY month;

التغير النسبي

يريد القائمون بالمقابلات عادةً معرفة النمو كنسبة مئوية. الصيغة هي (القيمة الحالية - القيمة السابقة) / القيمة السابقة، ثم الضرب في 100. عبّر عن ذلك مباشرةً باستخدام LAG.

انتبه إلى ترتيب العمليات والأقواس؛ فوضع أحدها في غير موضعه خطأ شائع تحت الضغط.

SELECT
  month,
  revenue,
  100.0 * (revenue - LAG(revenue) OVER (ORDER BY month))
        / LAG(revenue) OVER (ORDER BY month) AS pct_growth
FROM monthly_sales
ORDER BY month;

تجنب القسمة الصحيحة

من الأخطاء التي يقع فيها كثير من المرشحين: إذا كان revenue عددًا صحيحًا، فإن (110 - 100) / 100 تساوي 0 في قواعد البيانات التي تستخدم القسمة الصحيحة.

اضرب في 100.0، وهو ثابت عشري، أو استخدم CAST للتحويل إلى عدد عشري أولًا لإجبار النظام على إجراء حسابات الفاصلة العائمة. إن ذكرت ذلك استباقيًا، فأنت تُظهر اهتمامًا بالتفاصيل.

SELECT
  month,
  ROUND(
    100.0 * (revenue - LAG(revenue) OVER (ORDER BY month))
          / LAG(revenue) OVER (ORDER BY month), 2
  ) AS pct_growth
FROM monthly_sales;

أسلوب أنظف: احسب القيمة مرة واحدة في CTE

يؤدي استدعاء LAG مرتين، للبسط والمقام، إلى تكرار يسهل أن تخطئ في كتابته. ومن أساليب إعادة الهيكلة الشائعة حساب القيمة السابقة مرة واحدة في CTE، ثم إجراء العمليات الحسابية في الاستعلام الخارجي.

تكون هذه الصيغة أوضح في مقابلة تعتمد على الكتابة على اللوح، كما تتجنب اختلاف النتائج بين استدعاءي LAG.

WITH t AS (
  SELECT
    month,
    revenue,
    LAG(revenue) OVER (ORDER BY month) AS prev
  FROM monthly_sales
)
SELECT
  month,
  revenue,
  ROUND(100.0 * (revenue - prev) / prev, 2) AS pct_growth
FROM t;

الحماية من القسمة على صفر

إذا كان من الممكن أن تساوي قيمة الفترة السابقة 0، فستقسم صيغة التغير النسبي على صفر وتؤدي إلى خطأ. استخدم NULLIF(prev, 0) حتى يصبح المقام NULL، وتصبح النتيجة NULL بدلًا من حدوث استثناء.

القسمة الوقائية لمسة صغيرة يلاحظها القائمون بالمقابلات لدى المرشحين الذين يفكرون بعقلية الإنتاج.

SELECT
  month,
  revenue,
  100.0 * (revenue - prev) / NULLIF(prev, 0) AS pct_growth
FROM (
  SELECT month, revenue,
         LAG(revenue) OVER (ORDER BY month) AS prev
  FROM monthly_sales
) s;

التغير من فترة إلى أخرى لكل مجموعة

تتعلق معظم الأسئلة الواقعية بنطاق محدد: النمو من شهر إلى آخر لكل منتج أو لكل منطقة. أضف PARTITION BY حتى تُقارن سلسلة كل مجموعة بنفسها فقط.

تبدأ قيمة الشهر الأقدم في كل مجموعة بـ NULL، ولا تتم مقارنتها مطلقًا عبر حدود المنتجات.

SELECT
  product_id,
  month,
  revenue,
  revenue - LAG(revenue) OVER (
    PARTITION BY product_id
    ORDER BY month
  ) AS mom_change
FROM product_sales;

التغير من سنة إلى أخرى باستخدام الإزاحة

في المقارنة من سنة إلى أخرى للبيانات الشهرية التي تفصل بين صفوفها مدة شهر واحد، تقارن القيمة بالقيمة التي تسبقها 12 صفًا. وينفذ معامل الإزاحة ذلك مباشرةً: LAG(revenue, 12).

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

SELECT
  month,
  revenue,
  revenue - LAG(revenue, 12) OVER (ORDER BY month) AS yoy_change
FROM monthly_sales
ORDER BY month;

جمّع البيانات مسبقًا قبل المقارنة

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

تؤدي محاولة تطبيق LAG على صفوف غير مجمعة إلى مقارنة المعاملات الفردية، لا الإجماليات الشهرية، وهذا خطأ منطقي شائع.

WITH monthly AS (
  SELECT DATE_TRUNC('month', order_date) AS mth,
         SUM(amount) AS revenue
  FROM orders
  GROUP BY 1
)
SELECT mth, revenue,
       revenue - LAG(revenue) OVER (ORDER BY mth) AS mom_change
FROM monthly
ORDER BY mth;

تفسير أول قيمة NULL

قد يسأل القائمون بالمقابلات أحيانًا: «لماذا كان نمو الصف الأول NULL؟ وهل هذا مقبول؟» الإجابة الصحيحة هي أنه لا توجد فترة سابقة، ولذلك يكون التغير غير معرّف، وتمثل NULL هذه الحالة تمثيلًا صحيحًا.

إذا أراد النشاط التجاري القيمة 0 بدلًا من ذلك، فاستخدم LAG(revenue, 1, 0) أو COALESCE، ولكن فقط إذا كان ذلك يطابق المعنى المقصود.

تسمية اتجاه النمو

قد يوسّع القائمون بالمقابلات السؤال أحيانًا: «أضف أيضًا علامة توضّح ما إذا كان كل شهر قد نما أو انخفض أو بقي ثابتًا». ضع مقارنة LAG داخل تعبير CASE.

تمنح المقارنة بالقيمة السابقة عمود اتجاه واضحًا وسهل القراءة إلى جانب الفرق الرقمي، كما تعرض بسلاسة NULL أو تسمية افتراضية للفترة الأولى التي لا توجد لها مقارنة.

SELECT
  month,
  revenue,
  CASE
    WHEN revenue > LAG(revenue) OVER (ORDER BY month) THEN 'up'
    WHEN revenue < LAG(revenue) OVER (ORDER BY month) THEN 'down'
    ELSE 'flat'
  END AS trend
FROM monthly_sales
ORDER BY month;

تحقق سريع

حدّد الخطأ الشائع في استعلامات التغير النسبي.

مراجعة

التغير من فترة إلى أخرى هو LAG مضافًا إليه العمليات الحسابية:

  • التغير المطلق: value - LAG(value) OVER (ORDER BY period).
  • التغير النسبي: 100.0 * (value - prev) / NULLIF(prev, 0).
  • استخدم حسابات الفاصلة العائمة، واحمِ من القسمة على صفر، واجمع البيانات مسبقًا بحيث يكون هناك صف واحد لكل فترة.
  • حدّد النطاق باستخدام PARTITION BY، واستخدم الإزاحة للمقارنة من سنة إلى أخرى.

بعد ذلك: تقسيم الصفوف إلى شرائح ومستويات باستخدام NTILE.

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

هل درس «التغير من فترة إلى أخرى» مجاني؟

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

ماذا ستتعلم في «التغير من فترة إلى أخرى»؟

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

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

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

كم من الوقت يستغرق درس «التغير من فترة إلى أخرى»؟

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

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

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

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

  1. LAG وLEAD للصفوف المتجاورة
  2. التغير من فترة إلى أخرى
  3. NTILE لتقسيم الصفوف إلى مجموعات
  4. FIRST_VALUE وLAST_VALUE وحدود الإطار
← العودة إلى Coding Interview Prep