Kodokon kodokon.com

LEFT JOIN وNULL: العثور على ما هو مفقود

احتفظ بكل صف من جدول باستخدام LEFT JOIN، واكتشف الغيابات باستخدام IS NULL واستبدلها باستخدام COALESCE.

8 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

يخفي INNER JOIN في الدرس السابق العملاء الذين ليس لهم طلبات. ومع ذلك، فإن أكثر أسئلة العمل تكرارًا هو تحديدًا: من المفقود؟ العملاء غير النشطين، والمنتجات التي لم تُبَع قط، والفواتير التي بلا دفع... شغّل هذا السكربت في sqliteonline.com أو sqlite3: فهو يضيف عميلًا رابعًا بلا طلبات.

SQL
CREATE TABLE customers (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  city TEXT
);

CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  customer_id INTEGER NOT NULL,
  amount REAL NOT NULL
);

INSERT INTO customers (id, name, city) VALUES
  (1, 'Alice', 'Lyon'),
  (2, 'Karim', 'Paris'),
  (3, 'Mina', 'Nantes'),
  (4, 'Paulo', 'Lille');

INSERT INTO orders (id, customer_id, amount)
VALUES
  (1, 1, 49.90),
  (2, 1, 15.00),
  (3, 2, 120.50);
لم يضع مينا وباولو أيّ طلب.

يحتفظ LEFT JOIN بـ كل صفوف الجدول الأيسر (الجدول المذكور قبل الكلمة المفتاحية)، حتى دون تطابق في الجهة اليمنى. وعندما ينعدم التطابق، تُملأ أعمدة الجدول الأيمن بالقيمة NULL.

SQL
SELECT c.name, o.id AS order_id, o.amount
FROM customers AS c
LEFT JOIN orders AS o
  ON o.customer_id = c.id;
يظهر مينا وباولو، مع تعيين order_id وamount إلى NULL.

لعزل ما هو مفقود، صفِّ بناءً على قيم NULL هذه: وهذا هو نمط الربط العكسي (anti-join)، وهو رد فعل أساسي في تحليل البيانات. يجب أن يأتي العمود المُختبَر من الجدول الأيمن، وألّا يكون NULL بشكل طبيعي أبدًا، ومن هنا جاء اختيار مفتاحه الأساسي o.id.

SQL
SELECT c.name, c.city
FROM customers AS c
LEFT JOIN orders AS o
  ON o.customer_id = c.id
WHERE o.id IS NULL;
العملاء الذين لم يطلبوا قط: مينا وباولو.

أداة أخيرة: تُرجِع COALESCE(a, b) القيمة a إذا لم تكن NULL، وإلا فتُرجِع b. وبدمجها مع LEFT JOIN وتجميع، تحوّل الغيابات إلى أصفار قابلة للاستخدام في تقرير أو فاتورة.

SQL
SELECT c.name,
  COALESCE(SUM(o.amount), 0) AS total_spent
FROM customers AS c
LEFT JOIN orders AS o
  ON o.customer_id = c.id
GROUP BY c.id
ORDER BY total_spent DESC;
إجمالي الإنفاق لكل عميل، 0 بدلًا من NULL للعملاء غير النشطين.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. أيّ تركيبة تسرد العملاء الذين لم يطلبوا قط؟
    • INNER JOIN ثم WHERE o.id IS NULL
    • LEFT JOIN ثم WHERE o.id IS NULL
    • LEFT JOIN ثم WHERE o.id = NULL
  2. ماذا يُرجِع الشرط amount = NULL؟
    • صحيح للصفوف التي يكون فيها amount مساويًا لـ NULL
    • غير صحيح أبدًا: تبقى المقارنة غير معرّفة
    • خطأ في بناء الجملة
  3. ماذا يُرجِع COALESCE(SUM(o.amount), 0) لعميل ليس له طلبات؟
    • 0
    • NULL
    • يُستبعَد العميل من النتيجة
    • خطأ في التجميع