{"id":"l-sql-1-1","courseId":"sql-for-analysts","lang":"ar","kind":"intro","summary":"تعرّف على قاعدة بيانات Cartwheel، وحوّل طلبًا غامضًا إلى سؤال دقيق، ثم أجب عنه بـ SELECT والأعمدة المحسوبة وORDER BY وLIMIT.","html":"<p>في أسبوعك الأول في Cartwheel تصلك رسالة من رانيا عزيز، المديرة التنفيذية: «أيّ منتجاتنا غالية لكن ربحها ضئيل؟ أريد مراجعة الأسعار قبل كتالوج الربيع». يبدو الأمر بسيطًا، وهو في الوقت نفسه مثال مثالي على طبيعة العمل: شخص أمامه قرار حقيقي يطرح سؤالًا بكلمات عادية، وأنت تحوّله إلى query يجيب عن هذا السؤال بالضبط، لا أكثر ولا أقل.</p>\n<p>Cartwheel متجر إلكتروني لمستلزمات المنزل والأنشطة الخارجية، يبيع في ثماني دول. تحتوي قاعدة بيانات SQLite الخاصة به على سنتين من السجلات، من يناير 2024 حتى ديسمبر 2025. كل query في هذه الدورة يعمل عليها، داخل متصفّحك.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">تعرّف على قاعدة البيانات</h2>\n<p>قبل أن تكتب الـ query الحقيقي، ألقِ نظرة حولك. يحتفظ SQLite بفهرس لجداوله في <code dir=\"ltr\">sqlite_schema</code> (الكود القديم يسمّيه <code dir=\"ltr\">sqlite_master</code>، وما زال يعمل):</p>\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\">SELECT</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> name</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sqlite_schema</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">WHERE</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> type</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'table'</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>تسعة جداول. لترى أعمدة جدول واحد وأنواعها، اطلب قائمة أعمدته:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"sql\" data-run=\"sql\" data-index=\"1\"><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=\"1\" 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\">SELECT</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> name</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">type</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"notnull\"</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pragma_table_info(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'orders'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span></code></pre><div class=\"run-output\" data-run-output=\"1\" hidden></div></div>\n<p>وهذه طريقة ارتباط الجداول ببعضها. يشير كل سهم من جدول إلى الجدول الذي يرجع إليه، والتسمية هي المفتاح المشترك بينهما.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 720 300\" role=\"img\" aria-labelledby=\"l-sql-1-1-t1\"><defs><marker id=\"arrow-l-sql-1-1-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-1-1-t1\">العملاء يقدّمون الطلبات؛ الطلبات تحتوي على order_items؛ وorder_items ترجع إلى products، والمنتجات تنتمي إلى categories. المرتجعات returns ترجع إلى order_items. تذاكر الدعم support_tickets ترجع إلى customers وorders وemployees. وجلسات الموقع web_sessions ترجع إلى customers.</title>\n  <rect class=\"d-box\" x=\"20\" y=\"30\" width=\"150\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"95\" y=\"60\" text-anchor=\"middle\">web_sessions</text>\n  <rect class=\"d-box\" x=\"215\" y=\"30\" width=\"160\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"295\" y=\"60\" text-anchor=\"middle\">support_tickets</text>\n  <rect class=\"d-box\" x=\"420\" y=\"30\" width=\"140\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"490\" y=\"60\" text-anchor=\"middle\">employees</text>\n  <rect class=\"d-box-primary\" x=\"20\" y=\"140\" width=\"150\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label-strong\" x=\"95\" y=\"170\" text-anchor=\"middle\">customers</text>\n  <rect class=\"d-box-primary\" x=\"215\" y=\"140\" width=\"160\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label-strong\" x=\"295\" y=\"170\" text-anchor=\"middle\">orders</text>\n  <rect class=\"d-box-primary\" x=\"420\" y=\"140\" width=\"140\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label-strong\" x=\"490\" y=\"170\" text-anchor=\"middle\">order_items</text>\n  <rect class=\"d-box-accent\" x=\"595\" y=\"140\" width=\"110\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"650\" y=\"170\" text-anchor=\"middle\">products</text>\n  <rect class=\"d-box-accent\" x=\"595\" y=\"235\" width=\"110\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"650\" y=\"265\" text-anchor=\"middle\">categories</text>\n  <rect class=\"d-box\" x=\"420\" y=\"235\" width=\"140\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"490\" y=\"265\" text-anchor=\"middle\">returns</text>\n  <path class=\"d-arrow\" d=\"M215 165 L172 165\" marker-end=\"url(#arrow-l-sql-1-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M420 165 L377 165\" marker-end=\"url(#arrow-l-sql-1-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M560 165 L593 165\" marker-end=\"url(#arrow-l-sql-1-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M650 190 L650 233\" marker-end=\"url(#arrow-l-sql-1-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M490 235 L490 192\" marker-end=\"url(#arrow-l-sql-1-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M95 80 L95 138\" marker-end=\"url(#arrow-l-sql-1-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M260 80 L130 138\" marker-end=\"url(#arrow-l-sql-1-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M295 80 L295 138\" marker-end=\"url(#arrow-l-sql-1-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M375 55 L418 55\" marker-end=\"url(#arrow-l-sql-1-1-1)\"/>\n  <text class=\"d-code\" x=\"193\" y=\"210\" text-anchor=\"middle\">customer_id</text>\n  <text class=\"d-code\" x=\"398\" y=\"210\" text-anchor=\"middle\">order_id</text>\n  <text class=\"d-code\" x=\"578\" y=\"128\" text-anchor=\"middle\">product_id</text>\n</svg><figcaption>مخطط Cartwheel: الطلبات تقع بين العملاء والمنتجات</figcaption></figure>\n<p>الجداول الثلاثة المميّزة هي العمود الفقري لمعظم الأسئلة: العميل يقدّم طلبًا، والطلب يضمّ عنصرًا واحدًا أو أكثر. المال موجود في <code dir=\"ltr\">order_items</code> لا في <code dir=\"ltr\">orders</code>: إيراد السطر هو <code dir=\"ltr\">quantity * unit_price * (1 - discount)</code>.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">من الطلب إلى الـ query</h2>\n<p>في طلب رانيا كلمتان غامضتان. «غالية» قد تعني سعر القائمة. أما «ربحها ضئيل» فتحتاج إلى رقم: هامش الربح كنسبة مئوية من السعر، أي <code dir=\"ltr\">(unit_price - unit_cost) / unit_price</code>، هو الطريقة المعتادة لمقارنة قمع تقطير قهوة بسعر 22 دولارًا بمكتب بسعر 449 دولارًا. اكتب الصيغة الدقيقة قبل أن تبدأ الكتابة: <em>صف واحد لكل منتج، يعرض السعر ونسبة الهامش، والهوامش الأضعف أولًا.</em></p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"sql\" data-run=\"sql\" data-index=\"2\"><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=\"2\" 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\">SELECT</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  name</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  unit_price,</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  unit_cost,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  ROUND</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\"> unit_cost) </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:#0550AE;--shiki-dark:#79C0FF\"> 100</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\"> margin_pct</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> products</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">ORDER BY</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> margin_pct</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">LIMIT</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 5</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<p>ثلاث عادات تعمل هنا منذ الآن. العمود المحسوب يأخذ اسمًا مقروءًا بـ <code dir=\"ltr\">AS</code>. ويستطيع <code dir=\"ltr\">ORDER BY</code> أن يرتّب حسب هذا الاسم المستعار (alias). ويأتي <code dir=\"ltr\">LIMIT 5</code> في النهاية ليقصّ القائمة بعد ترتيبها.</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>LIMIT لا يعني «الأعلى»</span></p>\n<p><code dir=\"ltr\">LIMIT 5</code> بدون <code dir=\"ltr\">ORDER BY</code> يعطيك خمسة صفوف بأي ترتيب يصادف أن يقرأها به SQLite. كلما أردت «أعلى N» أو «أحدث N»، اكتب الـ <code dir=\"ltr\">ORDER BY</code> الذي يحدّد معنى الأعلى أو الأحدث، ثم الـ <code dir=\"ltr\">LIMIT</code>.</p>\n</aside>\n<h2 id=\"sec-3\" tabindex=\"-1\">حلقة عمل المحلّل</h2>\n<p>كل طلب في هذه الدورة يمرّ بالحلقة نفسها، ويستحق أن تجعلها عادة من الآن:</p>\n<ol>\n<li><strong>أعِد صياغة</strong> السؤال بدقة، بما في ذلك ما يمثّله الصف الواحد في الإجابة.</li>\n<li><strong>استكشف</strong> الجداول والأعمدة التي تحتاجها.</li>\n<li><strong>اكتب الـ query</strong>، وابدأ صغيرًا ثم وسّعه.</li>\n<li><strong>تحقّق من منطقية</strong> النتيجة: عدد الصفوف، مجموع تعرفه مسبقًا، حالة طرفية.</li>\n<li><strong>أجب</strong> بجملة يستطيع غير المحلّل أن يتصرّف بناءً عليها.</li>\n</ol>\n<p>بالنسبة إلى رانيا، قد تكون الخطوة 5 هكذا: «أضعف هوامشنا تقارب 40%، على Burr Coffee Grinder وCompact Writing Desk؛ ولا يوجد منتج معروض بأقل من تكلفته». جملة قصيرة ومحدّدة، وتقود إلى السؤال التالي.</p>\n<p>في الدرس التالي ستضيف أكثر عبارة استخدامًا في التحليل، <code dir=\"ltr\">WHERE</code>، وتتعلّم أين يتعثّر الناس في منطقها.</p>\n","toc":[{"id":"sec-1","text":"تعرّف على قاعدة البيانات","level":2},{"id":"sec-2","text":"من الطلب إلى الـ query","level":2},{"id":"sec-3","text":"حلقة عمل المحلّل","level":2}],"takeaways":["يبدأ الـ query عند المحلّل بسؤال دقيق، يشمل ما يمثّله الصف الواحد في الإجابة.","استكشف أي قاعدة بيانات جديدة عليك من خلال جداولها وأعمدتها قبل أن تكتب الـ query الحقيقي.","الأعمدة المحسوبة التي تحمل أسماء بـ AS تجعل النتيجة مقروءة دون أن تغيّر البيانات المخزّنة.","ORDER BY هو ما يحدّد الصفوف التي يُبقيها LIMIT، لذا فإن LIMIT بلا ORDER BY يعيد عيّنة اعتباطية لا يمكن الاعتماد عليها."],"further":[{"title":"SQLite SELECT statement","url":"https://www.sqlite.org/lang_select.html"},{"title":"The sqlite_schema table","url":"https://www.sqlite.org/schematab.html"}],"quiz":[{"q":"<p>تطلب رانيا «أفضل منتجاتنا». ماذا تفعل قبل أن تكتب أي SQL؟</p>","options":[{"text":"تحدّد بدقة ما تعنيه «أفضل» (الإيراد، أو عدد الوحدات، أو هامش الربح) وعن أي فترة.","why":"صحيح. لكلمة «أفضل» ثلاثة معانٍ مقبولة على الأقل، وكل معنى يعطي قائمة مختلفة. الاتفاق على المقياس أولًا يوفّر عليك إعادة الكتابة."},{"text":"تكتب <code dir=\"ltr\">SELECT * FROM products</code> وترسل إليها الجدول كاملًا.","why":"48 صفًا من الأعمدة الخام لا تجيب عن سؤال؛ إنها تعيد التحليل إلى من طلبه."},{"text":"ترتّب المنتجات حسب <code dir=\"ltr\">unit_price</code>، لأن المنتجات الغالية هي الأفضل.","why":"السعر ليس أداءً. مكتب بسعر 449 دولارًا يُباع مرتين في السنة قد يكون أقل أهمية من كوب بسعر 24 دولارًا يُباع كل يوم."}],"answer":0},{"q":"<p>ماذا يعيد هذا الـ query؟</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"sql\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">SQL</span><span class=\"code-actions\"><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\">SELECT</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> name</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, unit_price</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> products</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">LIMIT</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span></code></pre></div>\n","options":[{"text":"أغلى ثلاثة منتجات.","why":"لا شيء في الـ query يرتّب حسب السعر. LIMIT يقصّ النتيجة فقط، ولا يختار الصفوف «الأعلى» من تلقاء نفسه."},{"text":"أرخص ثلاثة منتجات.","why":"لا يوجد ORDER BY، فلا معنى لـ«الأرخص» هنا أيضًا."},{"text":"ثلاثة صفوف بأي ترتيب يقرؤها به SQLite، ولا يصحّ أن تعتمد عليه.","why":"صحيح. بدون ORDER BY يصبح ترتيب الصفوف تفصيلًا داخليًا في التنفيذ. اليوم هو ترتيب الإدخال، وبعد تغيير في الـ index قد لا يكون كذلك."}],"answer":2},{"q":"<p>تكتب <code dir=\"ltr\">unit_price - unit_cost AS margin</code> في قائمة SELECT. ماذا يحدث لجدول <code dir=\"ltr\">products</code>؟</p>","options":[{"text":"يُضاف عمود <code dir=\"ltr\">margin</code> جديد إلى الجدول بشكل دائم.","why":"SELECT لا يغيّر البيانات المخزّنة أبدًا. إضافة عمود تحتاج إلى ALTER TABLE."},{"text":"لا شيء؛ العمود <code dir=\"ltr\">margin</code> موجود في نتيجة هذا الـ query فقط.","why":"صحيح. العمود المحسوب يُحسب لكل صف في النتيجة ويختفي حين ينتهي الـ query."},{"text":"يفشل الـ query لأن <code dir=\"ltr\">margin</code> ليس عمودًا حقيقيًا.","why":"التعبيرات التي تحمل اسمًا مستعارًا هي بالضبط الطريقة التي تُنشئ بها أعمدة غير موجودة في الجدول."}],"answer":1}],"exercise":{"kind":"sql","starter":"-- Highest-margin products, by margin percent\nSELECT\n  name,\n  unit_price,\n  ROUND(unit_price - unit_cost, 2) AS margin\nFROM products\nORDER BY margin DESC\nLIMIT 5;","solution":"SELECT\n  name,\n  unit_price,\n  ROUND(unit_price - unit_cost, 2) AS margin,\n  ROUND((unit_price - unit_cost) / unit_price * 100, 1) AS margin_pct\nFROM products\nORDER BY margin_pct DESC\nLIMIT 5;","orderMatters":true,"title":"اعثر على أعلى هوامش الربح","prompt":"<p>أعجبت رانيا بقائمة الهوامش الضعيفة، وتريد الآن العكس: <strong>أعلى 5 منتجات من حيث نسبة هامش الربح</strong>، ليعرضها فريق التسويق.</p>\n<p>أعِد أربعة أعمدة بهذا الترتيب: <code dir=\"ltr\">name</code>، و<code dir=\"ltr\">unit_price</code>، و<code dir=\"ltr\">margin</code> (أي <code dir=\"ltr\">unit_price - unit_cost</code> مقرّبًا إلى منزلتين عشريتين)، و<code dir=\"ltr\">margin_pct</code> (الهامش كنسبة مئوية من <code dir=\"ltr\">unit_price</code> مقرّبًا إلى منزلة عشرية واحدة). رتّب حسب <code dir=\"ltr\">margin_pct</code> من الأعلى إلى الأدنى. الترتيب مهم.</p>\n<p>الكود المبدئي يرتّب حسب الهامش بالدولار، وهذا يحابي المنتجات الغالية. أصلحه.</p>\n","hints":["أضف عمودًا رابعًا يقسم الهامش على <code dir=\"ltr\">unit_price</code> ويضربه في 100.","ضعه داخل <code dir=\"ltr\">ROUND(..., 1)</code> وأعطه الاسم المستعار <code dir=\"ltr\">margin_pct</code>.","غيّر الـ <code dir=\"ltr\">ORDER BY</code> إلى <code dir=\"ltr\">margin_pct DESC</code>؛ ويبقى LIMIT في النهاية."],"explanation":"<p>الترتيب حسب الهامش بالدولار يضع Standing Desk في المقدمة، لأن السعر الكبير يترك فجوة كبيرة حتى مع نسبة عادية. أما نسبة الهامش فتقارن المنتجات بأي سعر على المقياس نفسه: Cable Management Kit بسعر 19 دولارًا يحتفظ بـ 61.5% من سعره، وهي الأفضل في الكتالوج. يستطيع <code dir=\"ltr\">ORDER BY</code> استخدام الاسم المستعار المعرّف في قائمة SELECT، ثم يُبقي <code dir=\"ltr\">LIMIT 5</code> أول خمسة صفوف من النتيجة المرتّبة.</p>\n","checkLabels":{}},"words":443,"readMinutes":3}