{"id":"l-sql-2-4","courseId":"sql-for-analysts","lang":"ar","kind":"lesson","summary":"اربط جدولًا بنفسه لتتبّع روابط المديرين والإحالات، واعثر على الصفوف التي لا تطابق لها باستخدام NOT EXISTS أو LEFT JOIN … IS NULL بدل NOT IN الهشّ أمام NULL.","html":"<p>يصل طلبان في الصباح نفسه. رانيا، المديرة التنفيذية، تريد قائمة واضحة بمن يتبع لمن قبل إعادة هيكلة. وهدى تريد أن تعرف أي العملاء سجّلوا ولم يشتروا شيئًا قط. يبدوان غير مترابطين، لكن كليهما عن العلاقات بين الصفوف: الأول يتتبّع رابطًا <em>داخل</em> جدول، والثاني يبحث عن روابط <em>مفقودة</em>.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">جدول مربوط بنفسه</h2>\n<p>في <code dir=\"ltr\">employees</code> يحمل <code dir=\"ltr\">manager_id</code> قيمة <code dir=\"ltr\">employee_id</code> لصف آخر في الجدول نفسه. لعرض كل موظف بجانب اسم مديره، تربط <code dir=\"ltr\">employees</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>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  e</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">first_name</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ||</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> ' '</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ||</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> e</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">last_name</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> employee,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  e</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">title</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  m</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">first_name</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ||</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> ' '</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ||</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> m</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">last_name</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> manager</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> employees </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> e</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">LEFT JOIN</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> employees </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> m</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  ON</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> m</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">employee_id</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> e</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">manager_id</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">ORDER BY</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> e</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">department</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, manager;</span></span></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<p>اقرأه كأنه نسختان من الجدول: <code dir=\"ltr\">e</code> هو الموظف، و<code dir=\"ltr\">m</code> هو من يتبع له. المعامل <code dir=\"ltr\">||</code> يدمج النصوص. يُبقي الـ LEFT JOIN رانيا نفسها، وقيمة <code dir=\"ltr\">manager_id</code> لديها NULL؛ أما الـ inner join فسيُسقط المديرة التنفيذية من الهيكل التنظيمي بصمت، وهذا ليس خطأً تودّ أن تشرحه لأحد.</p>\n<p>يعمل النمط نفسه على <code dir=\"ltr\">customers.referred_by</code>. من يجلب أكبر عدد من العملاء الجدد؟</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>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  r</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">customer_id</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  r</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">first_name</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ||</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> ' '</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ||</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\">last_name</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> referrer,</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\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> customers_referred</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</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>\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\"> 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\">customer_id</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</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\">referred_by</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">GROUP BY</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\">customer_id</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">ORDER BY</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> customers_referred </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">DESC</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\">customer_id</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=\"1\" hidden></div></div>\n<p>هنا <code dir=\"ltr\">c</code> هو العميل الجديد و<code dir=\"ltr\">r</code> هو المُحيل. أحال ليو إبراهيم ثلاثة أشخاص؛ ولم يُحِل أحدٌ أكثر منه. تسمية الأسماء المستعارة حسب الأدوار (<code dir=\"ltr\">e</code>/<code dir=\"ltr\">m</code>، <code dir=\"ltr\">c</code>/<code dir=\"ltr\">r</code>) بدل <code dir=\"ltr\">a</code>/<code dir=\"ltr\">b</code> هي ما يُبقي الـ self-joins مقروءة.</p>\n<p>الـ self-join يتقدّم مستوى واحدًا في كل مرة: من الموظف إلى المدير. أما «كل من في فريق بيتر، على أي عمق» فيحتاج إلى query تكراري، وستكتبه في القسم التالي.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">الـ semi-join: هل يوجد تطابق؟</h2>\n<p>في الدرس الماضي وجد <code dir=\"ltr\">WHERE order_id IN (SELECT order_id FROM support_tickets)</code> الطلبات التي لديها تذكرة واحدة على الأقل، دون الـ fan-out الذي يسبّبه الـ JOIN. هذا هو <strong>الـ semi-join</strong>. و<code dir=\"ltr\">EXISTS</code> هي الصياغة الشائعة الأخرى:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"sql\" data-index=\"2\"><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:#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:#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\">email</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</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>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">WHERE</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> EXISTS</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:#0550AE;--shiki-dark:#79C0FF\"> 1</span><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\">  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\">customer_id</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</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>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span></code></pre></div>\n<p>هذا الـ subquery <em>مترابط</em> (correlated): يشير إلى <code dir=\"ltr\">c</code> من الـ query الخارجي، فيُقيَّم لكل عميل. كتابة <code dir=\"ltr\">SELECT 1</code> عُرف متّبع؛ فـ EXISTS لا يهتم إلا بعودة صف ما، لا بما فيه.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">الـ anti-join: من ليس له تطابق؟</h2>\n<p>سؤال هدى عكس ذلك: العملاء الذين <strong>ليس</strong> لديهم طلبات. هناك طريقتان موثوقتان لكتابة الـ anti-join. الأولى هي <code dir=\"ltr\">NOT EXISTS</code>:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"sql\" data-run=\"sql\" data-index=\"3\"><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=\"3\" 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:#1F2328;--shiki-dark:#E6EDF3\">  strftime(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'%Y'</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\">signup_date</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\"> signup_year,</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\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> never_ordered</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</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>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">WHERE</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> NOT</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> EXISTS</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:#0550AE;--shiki-dark:#79C0FF\"> 1</span><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\">  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\">customer_id</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</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>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">GROUP BY</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> signup_year;</span></span></code></pre><div class=\"run-output\" data-run-output=\"3\" hidden></div></div>\n<p>85 عميلًا لم يطلبوا شيئًا قط، و52 منهم سجّلوا في 2024، أي قبل نهاية البيانات بسنة على الأقل. هذا هو الجزء الذي يمكن لهدى أن تتصرّف بناءً عليه: من سجّلوا في 2025 قد يتحوّلون إلى مشترين، أما من سجّلوا في 2024 فيحتاجون إلى حملة مختلفة.</p>\n<p>والطريقة الثانية LEFT JOIN لا تُبقي منه إلا الصفوف غير المطابقة:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"sql\" data-run=\"sql\" data-index=\"4\"><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=\"4\" 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:#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\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> never_ordered</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</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>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">LEFT JOIN</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 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\">customer_id</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</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>\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\">order_id</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> IS</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> NULL</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span></code></pre><div class=\"run-output\" data-run-output=\"4\" hidden></div></div>\n<p>العدد نفسه، 85. اختبر <strong>مفتاح</strong> الجدول الأيمن مقابل NULL، لأن المفتاح لا يكون NULL أبدًا في تطابق حقيقي. الصيغتان قياسيتان وسريعتان؛ ويفضّل معظم المحلّلين NOT EXISTS لأنه يصرّح بالنيّة ولا يمكن أن يسبّب fan-out.</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>NOT IN مع عمود يقبل NULL</span></p>\n<p>يسأل التسويق أي العملاء لم يُحيلوا أحدًا قط. <code dir=\"ltr\">WHERE customer_id NOT IN (SELECT referred_by FROM customers)</code> يبدو مثاليًا ولا يعيد <strong>أي صف</strong>. معظم العملاء قيمة <code dir=\"ltr\">referred_by</code> لديهم NULL، و<code dir=\"ltr\">5 NOT IN (58, 347, NULL)</code> قيمته غير معروفة لا TRUE، لأن الـ NULL قد تكون 5. قيمة NULL واحدة في الـ subquery تفرغ النتيجة كلها. استخدم NOT EXISTS، أو أضف <code dir=\"ltr\">WHERE referred_by IS NOT NULL</code> داخل الـ subquery إن كان لا بد من NOT IN.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">الـ anti-join مع شروط</h2>\n<p>الـ anti-joins الحقيقية تحمل عادةً شرطًا: ليس «لم يطلب قط»، بل «لم يطلب <em>مؤخرًا</em>». يذهب الشرط داخل الـ subquery الخاص بـ NOT EXISTS، حيث يضيّق الطلبات التي تُعدّ تطابقًا. هؤلاء هم العملاء الذين اشتروا في 2024 ولم يشتروا شيئًا في 2025، وهي قائمة كلاسيكية بالعملاء المنقطعين:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"sql\" data-run=\"sql\" data-index=\"5\"><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=\"5\" 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:#0550AE;--shiki-dark:#79C0FF\"> COUNT</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">DISTINCT</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:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">AS</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> lapsed_customers</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">FROM</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>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">JOIN</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\"> o24</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  ON</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> o24</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\"> c</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\"> AND</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> o24</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:#0A3069;--shiki-dark:#A5D6FF\"> '2025-01-01'</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">WHERE</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> NOT</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> EXISTS</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:#0550AE;--shiki-dark:#79C0FF\"> 1</span><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\"> o25</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  WHERE</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> o25</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\"> c</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\">    AND</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> o25</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:#0A3069;--shiki-dark:#A5D6FF\"> '2025-01-01'</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span></code></pre><div class=\"run-output\" data-run-output=\"5\" hidden></div></div>\n<p>الربط بطلبات 2024 يسبّب fan-out (العميل الذي لديه خمسة طلبات في 2024 يظهر خمس مرات)، لذا يعدّ الـ query العملاء دون تكرار (<code dir=\"ltr\">DISTINCT</code>). ووضع شرط 2025 في أي مكان خارج الـ subquery سيغيّر المعنى كليًا، وهو درس ON مقابل WHERE نفسه، لكن بمستوى أعمق.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">أيّها تستخدم</h2>\n<div class=\"table-wrap\" role=\"region\" aria-label=\"جدول قابل للتمرير\" tabindex=\"0\"><table><thead>\n<tr>\n<th>السؤال</th>\n<th>النمط</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>صفوف لها تطابق، دون تكرار</td>\n<td><code dir=\"ltr\">EXISTS</code> أو <code dir=\"ltr\">IN (subquery)</code></td>\n</tr>\n<tr>\n<td>صفوف ليس لها تطابق</td>\n<td><code dir=\"ltr\">NOT EXISTS</code>، أو <code dir=\"ltr\">LEFT JOIN ... WHERE key IS NULL</code></td>\n</tr>\n<tr>\n<td>صفوف مع تفاصيل تطابقها</td>\n<td><code dir=\"ltr\">JOIN</code> (انتبه للـ fan-out)</td>\n</tr>\n<tr>\n<td>روابط داخل جدول واحد</td>\n<td>self-join بأسماء مستعارة تحمل أسماء الأدوار</td>\n</tr>\n</tbody>\n</table></div><p>بهذا تكتمل أدوات الـ JOIN. يكدّس القسم التالي هذه اللبنات في تحليلات أطول، بدءًا بطريقة لتسمية النتائج الوسيطة حتى يُقرأ query من 40 سطرًا من الأعلى إلى الأسفل.</p>\n","toc":[{"id":"sec-1","text":"جدول مربوط بنفسه","level":2},{"id":"sec-2","text":"الـ semi-join: هل يوجد تطابق؟","level":2},{"id":"sec-3","text":"الـ anti-join: من ليس له تطابق؟","level":2},{"id":"sec-4","text":"الـ anti-join مع شروط","level":2},{"id":"sec-5","text":"أيّها تستخدم","level":2}],"takeaways":["الـ self-join يستخدم اسمين مستعارين للجدول نفسه، واحدًا لكل دور، مثل e للموظف وm للمدير.","الـ semi-join (عبر EXISTS أو IN) يُبقي الصفوف التي لها تطابق واحد على الأقل دون أن يضاعفها.","الـ anti-join يُبقي الصفوف التي لا تطابق لها؛ اكتبه بـ NOT EXISTS أو بـ LEFT JOIN … WHERE right_key IS NULL.","لا يعيد NOT IN أي صف حين يحتوي الـ subquery الخاص به على NULL، لذا تجنّبه مع الأعمدة التي تقبل NULL أو استبعد قيم NULL صراحةً."],"further":[{"title":"SQLite expressions, EXISTS and IN operators","url":"https://www.sqlite.org/lang_expr.html#the_exists_operator"},{"title":"PostgreSQL subquery expressions","url":"https://www.postgresql.org/docs/current/functions-subquery.html"}],"quiz":[{"q":"<p>في <code dir=\"ltr\">employees</code> يوجد 24 صفًا، والمديرة التنفيذية وحدها قيمة <code dir=\"ltr\">manager_id</code> لديها NULL. كم صفًا يعيد <code dir=\"ltr\">employees e JOIN employees m ON m.employee_id = e.manager_id</code>؟</p>","options":[{"text":"24","why":"قيمة <code dir=\"ltr\">manager_id</code> للمديرة التنفيذية NULL، فلا يجد الـ inner join لها صف مدير ويُسقطها."},{"text":"23","why":"صحيح. كل موظف ما عدا المديرة التنفيذية يطابق مديرًا واحدًا بالضبط. استخدم LEFT JOIN لإبقائها مع مدير قيمته NULL."},{"text":"576","why":"هذا 24 × 24، أي cross join. شرط ON يقصر كل موظف على مديره هو."}],"answer":1},{"q":"<p>بعض العملاء قيمة <code dir=\"ltr\">referred_by</code> لديهم NULL. ماذا يعيد <code dir=\"ltr\">SELECT COUNT(*) FROM customers WHERE customer_id NOT IN (SELECT referred_by FROM customers)</code>؟</p>","options":[{"text":"عدد العملاء الذين لم يُحيلوا أحدًا قط.","why":"هذا هو المقصود، لكن الـ subquery يحتوي على NULL، و<code dir=\"ltr\">x NOT IN (..., NULL)</code> لا يكون TRUE أبدًا."},{"text":"عدد العملاء الذين أحالوا أحدًا.","why":"NOT IN يستبعد المتطابقات، فلا يمكن أن يعيد المُحيلين، ومشكلة NULL تفرغ النتيجة على أي حال."},{"text":"0","why":"صحيح. لكل عميل تكون المقارنة مع NULL في القائمة غير معروفة، فتكون قيمة NOT IN إمّا NULL أو FALSE، ويحذف WHERE الصف."},{"text":"خطأ، لأن الـ subquery يعيد قيم NULL.","why":"يسمح SQL بقيم NULL في قائمة IN؛ يعمل الـ query ويعيد 0 بصمت."}],"answer":2},{"q":"<p>أي query يعرض العملاء الذين لم يقدّموا أي طلب قط؟</p>","options":[{"text":"<code dir=\"ltr\">SELECT c.* FROM customers c LEFT JOIN orders o ON o.customer_id = c.customer_id WHERE o.order_id IS NULL</code>","why":"صحيح. العملاء بلا طلبات يحصلون على <code dir=\"ltr\">o.order_id</code> قيمته NULL؛ أما من لديهم طلبات فلا، فيُبقي اختبار IS NULL غير المشترين بالضبط."},{"text":"<code dir=\"ltr\">SELECT c.* FROM customers c JOIN orders o ON o.customer_id = c.customer_id WHERE o.order_id IS NULL</code>","why":"الـ inner join حذف بالفعل العملاء الذين بلا طلبات، فلا يبقى شيء لتجده."},{"text":"<code dir=\"ltr\">SELECT c.* FROM customers c LEFT JOIN orders o ON o.customer_id = c.customer_id WHERE o.status IS NULL</code>","why":"قريب، ويعمل بالمصادفة لأن <code dir=\"ltr\">status</code> لا يقبل NULL، لكن اختبر مفتاح الربط؛ فعمود يقبل NULL مثل <code dir=\"ltr\">coupon_code</code> سيُمرّر مشترين حقيقيين."},{"text":"<code dir=\"ltr\">SELECT c.* FROM customers c WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id)</code>","why":"هذا هو الـ semi-join، وهو يُبقي المجموعة المعاكسة، أي العملاء الذين لديهم طلب واحد على الأقل."}],"answer":0}],"exercise":{"kind":"sql","starter":"-- Business customers who have never referred anyone\nSELECT customer_id, email, segment\nFROM customers\nWHERE segment IN ('enterprise', 'small_business')\n  AND customer_id NOT IN (SELECT referred_by FROM customers);","solution":"SELECT c.customer_id, c.email, c.segment\nFROM customers AS c\nWHERE c.segment IN ('enterprise', 'small_business')\n  AND NOT EXISTS (\n    SELECT 1\n    FROM customers AS r\n    WHERE r.referred_by = c.customer_id\n  );","orderMatters":false,"title":"من لم يُحِل أحدًا؟","prompt":"<p>تريد هدى أن تعرض برنامج الإحالة على حسابات الأعمال. اعرض كل عميل في شريحة <code dir=\"ltr\">enterprise</code> أو <code dir=\"ltr\">small_business</code> <strong>لم يُحِل أحدًا قط</strong> (لا يوجد عميل آخر يحمل معرّفه في <code dir=\"ltr\">referred_by</code>).</p>\n<p>أعِد <code dir=\"ltr\">customer_id</code> و<code dir=\"ltr\">email</code> و<code dir=\"ltr\">segment</code>. ترتيب الصفوف لا يهم. الكود المبدئي لا يعيد أي صف على الإطلاق؛ أعِد كتابة الـ anti-join حتى يعمل.</p>\n","hints":["شغّل <code dir=\"ltr\">SELECT referred_by FROM customers LIMIT 10</code>. ما القيمة التي يحملها معظم هذا العمود، وماذا يفعل NOT IN بها؟","أعِد كتابة الشرط بالصيغة <code dir=\"ltr\">NOT EXISTS (SELECT 1 FROM customers AS r WHERE r.referred_by = c.customer_id)</code>، مع إعطاء الجدول الخارجي الاسم المستعار <code dir=\"ltr\">c</code>.","أو أبقِ NOT IN لكن صفِّ الـ subquery: <code dir=\"ltr\">SELECT referred_by FROM customers WHERE referred_by IS NOT NULL</code>."],"explanation":"<p>يعيد الـ subquery الذي يلي NOT IN قائمة من 600 قيمة، 503 منها NULL. لا يمكن لـ <code dir=\"ltr\">x NOT IN (..., NULL)</code> أن يكون TRUE، لأن القيمة المجهولة قد تساوي x، فيُحذف كل صف. أما NOT EXISTS فيطرح سؤالًا بنعم أو لا لكل عميل (هل يوجد عميل قيمة <code dir=\"ltr\">referred_by</code> لديه هي أنا؟)، وقيم NULL لا تطابق شيئًا أبدًا، فيتصرّف كما هو مقصود: 88 عميل أعمال، 21 من enterprise و67 من small business، لم يُحيلوا أحدًا قط.</p>\n","checkLabels":{}},"words":652,"readMinutes":4}