EduFlow
SQL للمحلّلين
⁦0%⁩

الوحدة 4 · SQL في العالم الحقيقي

المشروع الختامي: مراجعة أعمال الربع الرابع

17 دقراءة 4 دتمرين SQL

الدرس في لمحة

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

  1. 1الخطوة 1: ثبّت التعريفات
  2. 2الخطوة 2: ابنِه في خطوات مسمّاة
  3. 3الخطوة 3: افحص قبل أن تصدّق
  4. 4الخطوة 4: اكتب الإجابة
  5. 5ما تستطيع فعله الآن

لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.

يأتي آخر طلب في السنة من رانيا نفسها: «سأعرض مراجعة الربع الرابع على مجلس الإدارة. كيف كان الربع الرابع من 2025 مقارنةً بالربع الرابع من 2024، دولةً دولة، وما القصة؟». هذه هي الدورة كلها في سؤال واحد. يحتاج إلى نطاقات تواريخ، وعمليات ربط بلا fan-out، وتجميع شرطي، وCTEs، وفحوص منطقية، وفي النهاية بضع جمل يستطيع مجلس الإدارة أن يتصرّف بناءً عليها. اعمل عليه كما تعمل على مكتب حقيقي: التعريفات أولًا، ثم الخطوات، ثم الفحوص، ثم الكلمات.

الخطوة 1: ثبّت التعريفات

قبل أي SQL، اكتب ما تعنيه كل كلمة في السؤال، وضعه حيث يستطيع الـ query أن يراه:

  • الربع الرابع: من 1 أكتوبر إلى 31 ديسمبر، يُصفّى كنطاقات نصف مفتوحة، من اليوم الأول في الربع حتى 1 يناير دون أن يشمله، لعامي 2024 و2025 كليهما.
  • الإيراد: مجموع quantity * unit_price * (1 - discount) من order_items، دون الشحن.
  • أي الطلبات: كل الحالات ما عدا ‘cancelled’، وهو التعريف المستخدم طوال هذه الدورة.
  • الدولة: دولة العميل، من customers.
  • مستوى تفصيل الإجابة: صف واحد لكل دولة.

توضع الفترات في CTE صغير خاص بها. كل خطوة لاحقة ترتبط به، فتغيير الربع يعني تعديل مكان واحد، لا ستة أماكن.

الخطوة 2: ابنِه في خطوات مسمّاة

periods (صف لكل ربع) وorder_revenue (صف لكل طلب) يغذّيان q4_orders (صف لكل طلب في الربع الرابع)، الذي يغذّي by_country (صف لكل دولة)، الذي يغذّي الـ SELECT الأخير الذي يضيف النمو ومتوسط قيمة الطلب. periods صف لكل ربع order_revenue صف لكل طلب q4_orders صف لكل طلب Q4 by_country صف لكل دولة SELECT النمو
query المشروع الختامي كسلسلة من الـ CTEs، لكلٍّ منها مستوى تفصيله
SQL
WITH periods AS (
  SELECT 'Q4 2024' AS period, '2024-10-01' AS start_date, '2025-01-01' AS end_date
  UNION ALL
  SELECT 'Q4 2025', '2025-10-01', '2026-01-01'
),
order_revenue AS (
  -- grain: one row per order
  SELECT order_id, SUM(quantity * unit_price * (1 - discount)) AS revenue
  FROM order_items
  GROUP BY order_id
),
q4_orders AS (
  -- grain: one row per non-cancelled Q4 order
  SELECT p.period, c.country, o.order_id, r.revenue
  FROM orders AS o
  JOIN periods AS p
    ON o.order_date >= p.start_date AND o.order_date < p.end_date
  JOIN customers AS c ON c.customer_id = o.customer_id
  JOIN order_revenue AS r ON r.order_id = o.order_id
  WHERE o.status <> 'cancelled'
),
by_country AS (
  -- grain: one row per country
  SELECT
    country,
    SUM(revenue) FILTER (WHERE period = 'Q4 2024') AS revenue_2024,
    SUM(revenue) FILTER (WHERE period = 'Q4 2025') AS revenue_2025,
    COUNT(*)     FILTER (WHERE period = 'Q4 2025') AS orders_2025
  FROM q4_orders
  GROUP BY country
)
SELECT
  country,
  ROUND(revenue_2024, 2) AS revenue_q4_2024,
  ROUND(revenue_2025, 2) AS revenue_q4_2025,
  ROUND(100.0 * (revenue_2025 - revenue_2024) / NULLIF(revenue_2024, 0), 1) AS growth_pct,
  ROUND(revenue_2025 / orders_2025, 2) AS avg_order_value_2025
FROM by_country
ORDER BY revenue_q4_2025 DESC;

وراء كل تقنية هنا درس. الربط بـ periods يستخدم شرط نطاق في ON، فيوسم كل طلب بربعه ويُسقط كل ما عداه. ويضغط order_revenue العناصر أولًا، فيعدّ COUNT(*) لاحقًا الطلبات. ويضع FILTER السنتين جنبًا إلى جنب في مرور واحد. ويحمي NULLIF حساب النمو من دولة لم تبِع شيئًا في السنة الماضية.

الخطوة 3: افحص قبل أن تصدّق

فحصان يستغرقان دقيقة ويلتقطان معظم الأخطاء. أولًا، طابِق: يجب أن تجمع قيم revenue_q4_2025 الثماني إلى المجموع الناتج عن query أبسط على orders وorder_items وحدهما، أي 146,825.44، ويجب أن يجمع عمود 2024 إلى 52,537.10. وهي كذلك، بفارق لا يتجاوز سنتًا بسبب التقريب، فلا fan-out ولا صفوف ضائعة. ثانيًا، عُد إلى مجموعة فحوص جودة البيانات. المنتجات الموضوعة في الفئة الخطأ لا تهم على مستوى الدولة. أما الطلبان المرتجعان بلا سجلات إرجاع، والطلبات الـ 63 التي ما زالت ‘processing’ أو ‘shipped’، فتهم: بعض إيراد الربع الرابع من 2025 قد يُلغى أو يُسترد لاحقًا.

الخطوة 4: اكتب الإجابة

الـ query ليس هو المُخرَج؛ الإجابة هي المُخرَج. هذا ما يذهب إلى رانيا:

بلغ إيراد الربع الرابع من 2025 نحو 146.8 ألفًا، ارتفاعًا من 52.5 ألفًا في الربع الرابع من 2024 (+179%)، وتضاعف إيراد كل دولة على الأقل. النمو نمو في الحجم لا في حجم السلة: ارتفعت الطلبات من 228 إلى 642 بينما ثبت متوسط قيمة الطلب عند نحو 230. أصبحت المملكة المتحدة الآن أكبر أسواقنا (26.5 ألفًا، ارتفاعًا من 5.4 آلاف). أما نمو الأردن بنسبة +627% فمن أساس صغير. تحفّظ: في نهاية السنة كان 63 طلبًا من الربع الرابع، معظمها من ديسمبر، لا يزال قيد التجهيز أو الشحن، فقد تقتطع الإلغاءات والمرتجعات من الربع الرابع قليلًا.

من ثلاث إلى خمس جمل، والأرقام المهمة، وتحفّظ واحد صادق. لاحظ ما لا تقوله: لماذا نما الحجم. يقترح درس الـ cohorts أين تنظر بعد ذلك: كم من هذه الطلبات جاء من عملاء جدد اكتُسبوا في أسابيع Black Friday. والإجابة الجيدة تنتهي عادةً بالإشارة إلى السؤال الجيد التالي.

ما تستطيع فعله الآن

عُد بنظرك إلى طلب الدرس الأول عن الهوامش الضعيفة. انتقلت من SELECT وLIMIT إلى تحليل من خمس خطوات مسمّاة، بفحوص مدمجة وخلاصة مكتوبة. والأهم أنك بنيت عادات: اكتب السؤال ومستوى التفصيل قبل الـ query، واستخدم نطاقات التواريخ نصف المفتوحة، وضع شروط الجدول الأيمن في ON، وجمّع قبل الربط، واستخدم NOT EXISTS لـ«أبدًا»، وطابِق كل مجموع، وتعامل مع قيم NULL والفحوص الفاشلة كأسئلة. هذه العادات تنتقل إلى أي قاعدة بيانات، وأي لهجة، وأي نشاط تجاري. التمرين أدناه هو الأخير، وستكتبه من صفحة بيضاء.

أهم النقاط

  • ابدأ أي تحليل حقيقي بتثبيت التعريفات (الفترات، والإيراد، والحالات) في مكان واحد، حتى تستخدمها كل الخطوات اللاحقة نفسها.
  • ابنِ الـ query كخطوات CTE بمستويات تفصيل صريحة، وجمّع إلى صف واحد لكل طلب قبل ربط أي شيء يتكرّر.
  • ضع فترات المقارنة جنبًا إلى جنب باستخدام FILTER، واحسب النمو باستخدام NULLIF حتى يعطي الأساس الصفري NULL بدل خطأ.
  • طابِق الجدول النهائي مع مجموع مستقل، واذكر تحفّظات البيانات قبل أن تكتب الخلاصة.
  • اعرض النتيجة بجمل بسيطة مع الأرقام التي تدعمها، بما في ذلك ما لا تستطيع البيانات أن تخبرك به بعد.

قراءات إضافية

تحقّق من فهمك

4 أسئلة

السؤال 1 من 4

نما إيراد الربع الرابع من 52,537 إلى 146,825 بينما بقي متوسط قيمة الطلب في حدود 230 في السنتين. ماذا يخبر ذلك رانيا؟

السؤال 2 من 4

نما إيراد الأردن في الربع الرابع بنسبة 627%، وهي الأعلى بين كل الدول. كيف يجب أن تعرضها المراجعة؟

السؤال 3 من 4

لماذا يجمّع query المشروع الختامي order_items في order_revenue قبل ربطه بالطلبات والعملاء؟

السؤال 4 من 4

في 31 ديسمبر ما زال 63 طلبًا من الربع الرابع لعام 2025 في حالة ‘processing’ أو ‘shipped’. كيف يجب أن تؤثّر في التقرير؟

تدريب

تمرين SQL

نمو الربع الرابع حسب القناة، من صفحة بيضاء

سؤال رانيا التالي من مجلس الإدارة: «أي قناة قادت النمو؟». اكتب الـ query من الصفر.

أعِد صفًا واحدًا لكل channel فيه revenue_q4_2024 وrevenue_q4_2025 (كلاهما مقرّب إلى منزلتين عشريتين) وgrowth_pct (نسبة التغيّر من الربع الرابع 2024 إلى الربع الرابع 2025، مقرّبة إلى منزلة عشرية واحدة). استخدم تعريفات المشروع الختامي: الربع الرابع من 1 أكتوبر إلى 31 ديسمبر، والإيراد هو إيراد العناصر (quantity * unit_price * (1 - discount))، وتُحسب كل الحالات ما عدا ‘cancelled’. ترتيب الصفوف لا يهم.

الجداول
customers
(customer_id, first_name, last_name, email, country, city, signup_date, segment, referred_by)
orders
(order_id, customer_id, order_date, status, channel, coupon_code, shipping_fee)
order_items
(order_item_id, order_id, product_id, quantity, unit_price, discount)
products
(product_id, name, category_id, unit_price, unit_cost, launched_on, is_active)
categories
(category_id, name, parent_id)
returns
(return_id, order_item_id, return_date, reason, refund_amount)
employees
(employee_id, first_name, last_name, title, department, manager_id, hire_date, salary)
support_tickets
(ticket_id, customer_id, order_id, opened_at, closed_at, priority, channel, satisfaction, agent_id)
web_sessions
(session_id, customer_id, started_at, source, device, pages_viewed, added_to_cart, purchased)
-- Q4 2025 vs Q4 2024 revenue by channel. Write it from scratch.
-- Definitions: Q4 = 1 Oct to 31 Dec (half-open ranges), revenue = item revenue,
-- every status except 'cancelled'.
-- Output: channel, revenue_q4_2024, revenue_q4_2025, growth_pct
SELECT channel
FROM orders
GROUP BY channel;جارٍ تحميل المحرّر…

Ctrl/⌘ + Enter للتشغيل · يعمل في بيئة معزولة داخل متصفّحك. لا شيء يغادر جهازك.