احتفظ بكل صف من جدول باستخدام LEFT JOIN، واكتشف الغيابات باستخدام IS NULL واستبدلها باستخدام COALESCE.
افتح هذا الدرس في Kodokonيخفي INNER JOIN في الدرس السابق العملاء الذين ليس لهم طلبات. ومع ذلك، فإن أكثر أسئلة العمل تكرارًا هو تحديدًا: من المفقود؟ العملاء غير النشطين، والمنتجات التي لم تُبَع قط، والفواتير التي بلا دفع... شغّل هذا السكربت في sqliteonline.com أو sqlite3: فهو يضيف عميلًا رابعًا بلا طلبات.
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.
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;لعزل ما هو مفقود، صفِّ بناءً على قيم NULL هذه: وهذا هو نمط الربط العكسي (anti-join)، وهو رد فعل أساسي في تحليل البيانات. يجب أن يأتي العمود المُختبَر من الجدول الأيمن، وألّا يكون NULL بشكل طبيعي أبدًا، ومن هنا جاء اختيار مفتاحه الأساسي o.id.
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 وتجميع، تحوّل الغيابات إلى أصفار قابلة للاستخدام في تقرير أو فاتورة.
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;