{"id":"l-sql-4-4","courseId":"sql-for-analysts","lang":"ar","kind":"lesson","summary":"اجمع الدورة كلها في تحليل واحد، يقارن الربع الرابع من 2025 بالربع الرابع من 2024 حسب الدولة عبر خطوات CTE مسمّاة، ويطابق المجاميع، ويذكر التحفّظات، ويكتب إجابة تستطيع المديرة التنفيذية أن تتصرّف بناءً عليها.","html":"<p>يأتي آخر طلب في السنة من رانيا نفسها: «سأعرض مراجعة الربع الرابع على مجلس الإدارة. كيف كان الربع الرابع من 2025 مقارنةً بالربع الرابع من 2024، دولةً دولة، وما القصة؟». هذه هي الدورة كلها في سؤال واحد. يحتاج إلى نطاقات تواريخ، وعمليات ربط بلا fan-out، وتجميع شرطي، وCTEs، وفحوص منطقية، وفي النهاية بضع جمل يستطيع مجلس الإدارة أن يتصرّف بناءً عليها. اعمل عليه كما تعمل على مكتب حقيقي: التعريفات أولًا، ثم الخطوات، ثم الفحوص، ثم الكلمات.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">الخطوة 1: ثبّت التعريفات</h2>\n<p>قبل أي SQL، اكتب ما تعنيه كل كلمة في السؤال، وضعه حيث يستطيع الـ query أن يراه:</p>\n<ul>\n<li><strong>الربع الرابع</strong>: من 1 أكتوبر إلى 31 ديسمبر، يُصفّى كنطاقات نصف مفتوحة، من اليوم الأول في الربع حتى 1 يناير دون أن يشمله، لعامي 2024 و2025 كليهما.</li>\n<li><strong>الإيراد</strong>: مجموع <code dir=\"ltr\">quantity * unit_price * (1 - discount)</code> من <code dir=\"ltr\">order_items</code>، دون الشحن.</li>\n<li><strong>أي الطلبات</strong>: كل الحالات ما عدا ‘cancelled’، وهو التعريف المستخدم طوال هذه الدورة.</li>\n<li><strong>الدولة</strong>: دولة العميل، من <code dir=\"ltr\">customers</code>.</li>\n<li><strong>مستوى تفصيل الإجابة</strong>: صف واحد لكل دولة.</li>\n</ul>\n<p>توضع الفترات في CTE صغير خاص بها. كل خطوة لاحقة ترتبط به، فتغيير الربع يعني تعديل مكان واحد، لا ستة أماكن.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">الخطوة 2: ابنِه في خطوات مسمّاة</h2>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 720 210\" role=\"img\" aria-labelledby=\"l-sql-4-4-t1\"><defs><marker id=\"arrow-l-sql-4-4-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-sql-4-4-t1\">periods (صف لكل ربع) وorder_revenue (صف لكل طلب) يغذّيان q4_orders (صف لكل طلب في الربع الرابع)، الذي يغذّي by_country (صف لكل دولة)، الذي يغذّي الـ SELECT الأخير الذي يضيف النمو ومتوسط قيمة الطلب.</title>\n  <rect class=\"d-box-accent\" x=\"20\" y=\"30\" width=\"160\" height=\"50\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"100\" y=\"52\" text-anchor=\"middle\">periods</text>\n  <text class=\"d-label-muted\" x=\"100\" y=\"71\" text-anchor=\"middle\">صف لكل ربع</text>\n  <rect class=\"d-box-accent\" x=\"20\" y=\"130\" width=\"160\" height=\"50\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"100\" y=\"152\" text-anchor=\"middle\">order_revenue</text>\n  <text class=\"d-label-muted\" x=\"100\" y=\"171\" text-anchor=\"middle\">صف لكل طلب</text>\n  <rect class=\"d-box-primary\" x=\"230\" y=\"80\" width=\"150\" height=\"50\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"305\" y=\"102\" text-anchor=\"middle\">q4_orders</text>\n  <text class=\"d-label-muted\" x=\"305\" y=\"121\" text-anchor=\"middle\">صف لكل طلب Q4</text>\n  <rect class=\"d-box-primary\" x=\"420\" y=\"80\" width=\"140\" height=\"50\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"490\" y=\"102\" text-anchor=\"middle\">by_country</text>\n  <text class=\"d-label-muted\" x=\"490\" y=\"121\" text-anchor=\"middle\">صف لكل دولة</text>\n  <rect class=\"d-box-success\" x=\"600\" y=\"80\" width=\"105\" height=\"50\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"652\" y=\"102\" text-anchor=\"middle\">SELECT</text>\n  <text class=\"d-label-muted\" x=\"652\" y=\"121\" text-anchor=\"middle\">النمو</text>\n  <path class=\"d-arrow\" d=\"M180 60 L228 95\" marker-end=\"url(#arrow-l-sql-4-4-1)\"/>\n  <path class=\"d-arrow\" d=\"M180 150 L228 115\" marker-end=\"url(#arrow-l-sql-4-4-1)\"/>\n  <path class=\"d-arrow\" d=\"M380 105 L418 105\" marker-end=\"url(#arrow-l-sql-4-4-1)\"/>\n  <path class=\"d-arrow\" d=\"M560 105 L598 105\" marker-end=\"url(#arrow-l-sql-4-4-1)\"/>\n</svg><figcaption>query المشروع الختامي كسلسلة من الـ CTEs، لكلٍّ منها مستوى تفصيله</figcaption></figure>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"sql\" data-run=\"sql\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">SQL</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"sql\" data-index=\"0\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">WITH</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> periods </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  SELECT</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Q4 2024'</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> AS</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> period</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'2024-10-01'</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> AS</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> start_date</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'2025-01-01'</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> end_date</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  UNION ALL</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  SELECT</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Q4 2025'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'2025-10-01'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'2026-01-01'</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">),</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">order_revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span></span>\n<span class=\"line\"><span style=\"color:#6E7781;--shiki-dark:#8B949E\">  -- grain: one row per order</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  SELECT</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> order_id, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">SUM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(quantity </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> unit_price </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> -</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> discount)) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> revenue</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  FROM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> order_items</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  GROUP BY</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> order_id</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">),</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">q4_orders </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span></span>\n<span class=\"line\"><span style=\"color:#6E7781;--shiki-dark:#8B949E\">  -- grain: one row per non-cancelled Q4 order</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  SELECT</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> p</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">period</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">c</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">country</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">o</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">order_id</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">r</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">revenue</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  FROM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> orders </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> o</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  JOIN</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> periods </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> p</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    ON</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> o</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">order_date</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> >=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> p</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">start_date</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> AND</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> o</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">order_date</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> &#x3C;</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> p</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">end_date</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  JOIN</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> customers </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> c </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">ON</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> c</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">customer_id</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> o</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">customer_id</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  JOIN</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> order_revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> r </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">ON</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> r</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">order_id</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> o</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">order_id</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  WHERE</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> o</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">status</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> &#x3C;></span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'cancelled'</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">),</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">by_country </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span></span>\n<span class=\"line\"><span style=\"color:#6E7781;--shiki-dark:#8B949E\">  -- grain: one row per country</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  SELECT</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    country,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">    SUM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FILTER</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">WHERE</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> period</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Q4 2024'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> revenue_2024,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">    SUM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FILTER</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">WHERE</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> period</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Q4 2025'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> revenue_2025,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">    COUNT</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)     </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FILTER</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">WHERE</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> period</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Q4 2025'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> orders_2025</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  FROM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> q4_orders</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  GROUP BY</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> country</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">SELECT</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  country,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  ROUND</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue_2024, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> revenue_q4_2024,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  ROUND</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue_2025, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> revenue_q4_2025,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  ROUND</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">100</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> *</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (revenue_2025 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> revenue_2024) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">/</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> NULLIF</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue_2024, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">), </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> growth_pct,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  ROUND</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue_2025 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">/</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> orders_2025, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> avg_order_value_2025</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> by_country</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">ORDER BY</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> revenue_q4_2025 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">DESC</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<p>وراء كل تقنية هنا درس. الربط بـ <code dir=\"ltr\">periods</code> يستخدم شرط نطاق في ON، فيوسم كل طلب بربعه ويُسقط كل ما عداه. ويضغط <code dir=\"ltr\">order_revenue</code> العناصر أولًا، فيعدّ <code dir=\"ltr\">COUNT(*)</code> لاحقًا الطلبات. ويضع <code dir=\"ltr\">FILTER</code> السنتين جنبًا إلى جنب في مرور واحد. ويحمي <code dir=\"ltr\">NULLIF</code> حساب النمو من دولة لم تبِع شيئًا في السنة الماضية.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">الخطوة 3: افحص قبل أن تصدّق</h2>\n<p>فحصان يستغرقان دقيقة ويلتقطان معظم الأخطاء. أولًا، <strong>طابِق</strong>: يجب أن تجمع قيم <code dir=\"ltr\">revenue_q4_2025</code> الثماني إلى المجموع الناتج عن query أبسط على <code dir=\"ltr\">orders</code> و<code dir=\"ltr\">order_items</code> وحدهما، أي 146,825.44، ويجب أن يجمع عمود 2024 إلى 52,537.10. وهي كذلك، بفارق لا يتجاوز سنتًا بسبب التقريب، فلا fan-out ولا صفوف ضائعة. ثانيًا، <strong>عُد إلى مجموعة فحوص جودة البيانات</strong>. المنتجات الموضوعة في الفئة الخطأ لا تهم على مستوى الدولة. أما الطلبان المرتجعان بلا سجلات إرجاع، والطلبات الـ 63 التي ما زالت ‘processing’ أو ‘shipped’، فتهم: بعض إيراد الربع الرابع من 2025 قد يُلغى أو يُسترد لاحقًا.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>عرض نسبة مئوية بلا أساسها</span></p>\n<p>نما إيراد الأردن بنسبة 627%، وهي أكبر رقم على الشريحة، من نحو 790 إلى 5,760. ضع هذه النسبة وحدها في عنوان رئيسي، وسيسأل مجلس الإدارة عن الأردن عشرين دقيقة. اعرض النمو دائمًا بجانب القيم المطلقة، ونبّه إلى الأساسات الصغيرة صراحةً.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">الخطوة 4: اكتب الإجابة</h2>\n<p>الـ query ليس هو المُخرَج؛ الإجابة هي المُخرَج. هذا ما يذهب إلى رانيا:</p>\n<blockquote>\n<p>بلغ إيراد الربع الرابع من 2025 نحو 146.8 ألفًا، ارتفاعًا من 52.5 ألفًا في الربع الرابع من 2024 (+179%)، وتضاعف إيراد كل دولة على الأقل. النمو نمو في الحجم لا في حجم السلة: ارتفعت الطلبات من 228 إلى 642 بينما ثبت متوسط قيمة الطلب عند نحو 230. أصبحت المملكة المتحدة الآن أكبر أسواقنا (26.5 ألفًا، ارتفاعًا من 5.4 آلاف). أما نمو الأردن بنسبة +627% فمن أساس صغير. تحفّظ: في نهاية السنة كان 63 طلبًا من الربع الرابع، معظمها من ديسمبر، لا يزال قيد التجهيز أو الشحن، فقد تقتطع الإلغاءات والمرتجعات من الربع الرابع قليلًا.</p>\n</blockquote>\n<p>من ثلاث إلى خمس جمل، والأرقام المهمة، وتحفّظ واحد صادق. لاحظ ما لا تقوله: <em>لماذا</em> نما الحجم. يقترح درس الـ cohorts أين تنظر بعد ذلك: كم من هذه الطلبات جاء من عملاء جدد اكتُسبوا في أسابيع Black Friday. والإجابة الجيدة تنتهي عادةً بالإشارة إلى السؤال الجيد التالي.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">ما تستطيع فعله الآن</h2>\n<p>عُد بنظرك إلى طلب الدرس الأول عن الهوامش الضعيفة. انتقلت من SELECT وLIMIT إلى تحليل من خمس خطوات مسمّاة، بفحوص مدمجة وخلاصة مكتوبة. والأهم أنك بنيت عادات: اكتب السؤال ومستوى التفصيل قبل الـ query، واستخدم نطاقات التواريخ نصف المفتوحة، وضع شروط الجدول الأيمن في ON، وجمّع قبل الربط، واستخدم NOT EXISTS لـ«أبدًا»، وطابِق كل مجموع، وتعامل مع قيم NULL والفحوص الفاشلة كأسئلة. هذه العادات تنتقل إلى أي قاعدة بيانات، وأي لهجة، وأي نشاط تجاري. التمرين أدناه هو الأخير، وستكتبه من صفحة بيضاء.</p>\n","toc":[{"id":"sec-1","text":"الخطوة 1: ثبّت التعريفات","level":2},{"id":"sec-2","text":"الخطوة 2: ابنِه في خطوات مسمّاة","level":2},{"id":"sec-3","text":"الخطوة 3: افحص قبل أن تصدّق","level":2},{"id":"sec-4","text":"الخطوة 4: اكتب الإجابة","level":2},{"id":"sec-5","text":"ما تستطيع فعله الآن","level":2}],"takeaways":["ابدأ أي تحليل حقيقي بتثبيت التعريفات (الفترات، والإيراد، والحالات) في مكان واحد، حتى تستخدمها كل الخطوات اللاحقة نفسها.","ابنِ الـ query كخطوات CTE بمستويات تفصيل صريحة، وجمّع إلى صف واحد لكل طلب قبل ربط أي شيء يتكرّر.","ضع فترات المقارنة جنبًا إلى جنب باستخدام FILTER، واحسب النمو باستخدام NULLIF حتى يعطي الأساس الصفري NULL بدل خطأ.","طابِق الجدول النهائي مع مجموع مستقل، واذكر تحفّظات البيانات قبل أن تكتب الخلاصة.","اعرض النتيجة بجمل بسيطة مع الأرقام التي تدعمها، بما في ذلك ما لا تستطيع البيانات أن تخبرك به بعد."],"further":[{"title":"SQLite WITH clause","url":"https://www.sqlite.org/lang_with.html"},{"title":"SQLite aggregate functions and FILTER","url":"https://www.sqlite.org/lang_aggfunc.html"}],"quiz":[{"q":"<p>نما إيراد الربع الرابع من 52,537 إلى 146,825 بينما بقي متوسط قيمة الطلب في حدود 230 في السنتين. ماذا يخبر ذلك رانيا؟</p>","options":[{"text":"العملاء ينفقون أكثر بكثير في كل طلب.","why":"متوسط قيمة الطلب بالكاد تحرّك، فحجم السلة ليس هو المحرّك."},{"text":"ارتفعت الأسعار بشدة بين الربعين.","why":"كانت زيادة الأسعار في مارس 2025 بنسبة 5%، وهي بعيدة جدًا عن تفسير تضاعف الإيراد قرابة ثلاث مرات، وكانت ستظهر كارتفاع في قيمة الطلب."},{"text":"جاء النمو من طلبات أكثر، لا من طلبات أكبر.","why":"صحيح. ارتفعت الطلبات من 228 إلى 642 بقيمة متشابهة لكل طلب، فالقصة قصة حجم، وهذا يشير إلى اكتساب العملاء وتكرار الشراء."},{"text":"لا بد أن البيانات خاطئة لأن النمو فوق 100% مستحيل.","why":"يمكن للإيراد أن يتضاعف وأكثر من أساس صغير. طابِق وافحص البيانات، لكن لا تفترض أن النمو الكبير خطأ."}],"answer":2},{"q":"<p>نما إيراد الأردن في الربع الرابع بنسبة 627%، وهي الأعلى بين كل الدول. كيف يجب أن تعرضها المراجعة؟</p>","options":[{"text":"اجعلها العنوان الرئيسي لنجاح الربع.","why":"النسب المئوية على أساس صغير جدًا هشّة؛ بضعة طلبات كبيرة قد تنتجها."},{"text":"اعرضها مع الأساس، من نحو 790 إلى 5,760، ونبّه إلى أن الأساس الصغير يجعل النسبة متقلّبة.","why":"صحيح. الأرقام المطلقة تتيح للقارئ تقدير حجم التغيّر، وهو ما تخفيه النسبة وحدها."},{"text":"استبعد الأردن لأنها قيمة شاذة.","why":"إسقاط دولة يغيّر المجموع ويخفي نموًا حقيقيًا. الحل هو السياق، لا الحذف."},{"text":"استبدل النسبة بمتوسط نمو كل الدول.","why":"هذا يعرض رقمًا ليس رقم الأردن، وهو مضلّل أكثر من الأصل."}],"answer":1},{"q":"<p>لماذا يجمّع query المشروع الختامي <code dir=\"ltr\">order_items</code> في <code dir=\"ltr\">order_revenue</code> قبل ربطه بالطلبات والعملاء؟</p>","options":[{"text":"لأن SQLite لا يستطيع ربط أكثر من ثلاثة جداول.","why":"يتعامل SQLite مع عمليات ربط كثيرة؛ هذه الخطوة تتعلّق بمستوى تفصيل البيانات، لا بحدود المحرّك."},{"text":"لجعل الـ query أسرع.","why":"قد يكون أسرع وقد لا يكون؛ سبب وجودها هو الصحة."},{"text":"لإزالة الطلبات الملغاة.","why":"تُستبعد الطلبات الملغاة بشرط WHERE على <code dir=\"ltr\">orders.status</code>، في خطوة لاحقة."},{"text":"حتى تعمل كل خطوة لاحقة بصف واحد لكل طلب، ولا تكرّر سطور العناصر أعداد الطلبات وقيمها.","why":"صحيح. مع ضغط العناصر أولًا يعدّ <code dir=\"ltr\">COUNT(*)</code> الطلبات ولا يحدث fan-out، وهو درس قسم الـ JOIN."}],"answer":3},{"q":"<p>في 31 ديسمبر ما زال 63 طلبًا من الربع الرابع لعام 2025 في حالة ‘processing’ أو ‘shipped’. كيف يجب أن تؤثّر في التقرير؟</p>","options":[{"text":"احسبها ضمن الإيراد لكن اذكر أن بعضها قد يُلغى أو يُرتجع، فقد ينكمش الربع الرابع من 2025 قليلًا.","why":"صحيح. إنها تستوفي التعريف المتفق عليه (غير ملغاة)، وتسمية الخطر القائم تُبقي الرقم صادقًا."},{"text":"استبعدها، لأن الإيراد لا يحسب إلا الطلبات المسلَّمة.","why":"هذا يغيّر التعريف المستخدم في كل مكان آخر في الدورة في منتصف التحليل؛ التعريفات يجب أن تتغيّر عن قصد، لا بصمت."},{"text":"تجاهل المسألة؛ الحالة لا تؤثّر في الإيراد.","why":"الحالة تؤثّر فعلًا، لأن الإلغاءات والمرتجعات تغيّر ما يحتفظ به النشاط فعليًا."}],"answer":0}],"exercise":{"kind":"sql","starter":"-- Q4 2025 vs Q4 2024 revenue by channel. Write it from scratch.\n-- Definitions: Q4 = 1 Oct to 31 Dec (half-open ranges), revenue = item revenue,\n-- every status except 'cancelled'.\n-- Output: channel, revenue_q4_2024, revenue_q4_2025, growth_pct\nSELECT channel\nFROM orders\nGROUP BY channel;","solution":"WITH order_revenue AS (\n  -- grain: one row per order\n  SELECT order_id, SUM(quantity * unit_price * (1 - discount)) AS revenue\n  FROM order_items\n  GROUP BY order_id\n),\nq4_orders AS (\n  -- grain: one row per non-cancelled Q4 order\n  SELECT\n    o.channel,\n    CASE WHEN o.order_date < '2025-01-01' THEN 'Q4 2024' ELSE 'Q4 2025' END AS period,\n    r.revenue\n  FROM orders AS o\n  JOIN order_revenue AS r ON r.order_id = o.order_id\n  WHERE o.status <> 'cancelled'\n    AND (\n      (o.order_date >= '2024-10-01' AND o.order_date < '2025-01-01')\n      OR (o.order_date >= '2025-10-01' AND o.order_date < '2026-01-01')\n    )\n)\nSELECT\n  channel,\n  ROUND(SUM(revenue) FILTER (WHERE period = 'Q4 2024'), 2) AS revenue_q4_2024,\n  ROUND(SUM(revenue) FILTER (WHERE period = 'Q4 2025'), 2) AS revenue_q4_2025,\n  ROUND(100.0 * (SUM(revenue) FILTER (WHERE period = 'Q4 2025')\n               - SUM(revenue) FILTER (WHERE period = 'Q4 2024'))\n        / NULLIF(SUM(revenue) FILTER (WHERE period = 'Q4 2024'), 0), 1) AS growth_pct\nFROM q4_orders\nGROUP BY channel;","orderMatters":false,"title":"نمو الربع الرابع حسب القناة، من صفحة بيضاء","prompt":"<p>سؤال رانيا التالي من مجلس الإدارة: «أي قناة قادت النمو؟». اكتب الـ query <strong>من الصفر</strong>.</p>\n<p>أعِد صفًا واحدًا لكل <code dir=\"ltr\">channel</code> فيه <code dir=\"ltr\">revenue_q4_2024</code> و<code dir=\"ltr\">revenue_q4_2025</code> (كلاهما مقرّب إلى منزلتين عشريتين) و<code dir=\"ltr\">growth_pct</code> (نسبة التغيّر من الربع الرابع 2024 إلى الربع الرابع 2025، مقرّبة إلى منزلة عشرية واحدة). استخدم تعريفات المشروع الختامي: الربع الرابع من 1 أكتوبر إلى 31 ديسمبر، والإيراد هو إيراد العناصر (<code dir=\"ltr\">quantity * unit_price * (1 - discount)</code>)، وتُحسب كل الحالات ما عدا ‘cancelled’. ترتيب الصفوف لا يهم.</p>\n","hints":["خطّط للخطوات أولًا: الإيراد لكل طلب، ثم طلبات الربع الرابع في السنتين موسومة بفترتها، ثم صف واحد لكل قناة.","وسِم فترة كل طلب بتعبير CASE على <code dir=\"ltr\">order_date</code>، بعد تصفية النطاقين الخاصين بالربع الرابع (انتبه للأقواس حول OR).","استخدم <code dir=\"ltr\">SUM(revenue) FILTER (WHERE period = 'Q4 2024')</code> والشيء نفسه لعام 2025، ثم <code dir=\"ltr\">100.0 * (new - old) / NULLIF(old, 0)</code> للنمو."],"explanation":"<p>ضغط العناصر في صف واحد لكل طلب يُبقي مستوى التفصيل نظيفًا، والنطاقات نصف المفتوحة تُبقي كل أيام الربع الرابع، وFILTER يضع السنتين في صف واحد لكل قناة. الإجابة لمجلس الإدارة: تضاعف الويب أكثر من ثلاث مرات (من نحو 27.8 ألفًا إلى 87.5 ألفًا، +214.6%) ونما التطبيق بنسبة 168%، بينما نما الـ marketplace بوتيرة أبطأ بلغت 81%. قنواتكم الخاصة هي التي قادت النمو. والـ query الذي يسم الفترات بالربط بـ CTE صغير اسمه <code dir=\"ltr\">periods</code>، كما في الدرس، صحيح بالقدر نفسه.</p>\n","checkLabels":{}},"words":638,"readMinutes":4}