LEFT JOIN و ردیفهای بیجفت
با LEFT JOIN همهی ردیفهای یک جدول را نگه داری، بیجفتها را پیدا کنی و تفاوت شرط در ON و WHERE را بدانی.
15 دقیقه مطالعه · 5 سؤال تمرینی · SQL از صفر: پرسوجو برای تحلیل داده
LEFT JOIN: چپیها را هیچوقت از دست نده
گاهی سؤال برعکس است: «همهی مشتریها را بده، حتی آنها که سفارش ندارند.» LEFT JOIN همهی ردیفهای جدول چپ (اولی) را نگه میدارد. اگر جفتی در جدول راست نباشد، ستونهای راست NULL میشوند:
SELECT c.name, o.id AS order_id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id;
| name | order_id | |---|---| | Sara | 101 | | ... | ... | | Reza | NULL | | Pouya | NULL |
از همین NULL برای پیدا کردن بیجفتها استفاده میکنیم (الگوی «anti-join»): مشتریهایی که هیچ سفارشی ندارند:
SELECT c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;
دو تلهی LEFT JOIN
تلهی ۱: شمارش. بعد از LEFT JOIN، ردیف مشتری بیسفارش با NULL هنوز یک ردیف است. پس:
SELECT c.name, COUNT(*) AS wrong, COUNT(o.id) AS right
FROM customers c LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;
برای Pouya، COUNT(*) برابر ۱ است (خود ردیف) ولی COUNT(o.id) برابر ۰ (سفارشی نیست). برای شمردن «تعداد سفارش» همیشه ستونی از جدول راست را بشمارید.
تلهی ۲: شرط روی جدول راست در WHERE. اگر بنویسید LEFT JOIN orders o ON ... WHERE o.status = 'paid'، ردیفهای بیجفت (که o.status در آنها NULL است) حذف میشوند و LEFT JOIN عملاً INNER JOIN میشود. اگر میخواهید فقط سفارشهای paid جفت شوند ولی مشتریها بمانند، شرط را به ON ببرید:
LEFT JOIN orders o ON o.customer_id = c.id AND o.status = 'paid'