خانه/ وبلاگ/ تفاوت انواع JOIN در SQL با مثال: INNER، LEFT، RIGHT و FULL
آموزش SQL

تفاوت انواع JOIN در SQL با مثال: INNER، LEFT، RIGHT و FULL

آموزش SQL ۵ آبان ۱۴۰۵ 12 دقیقه مطالعه

JOIN ابزار وصل کردن اطلاعات چند جدول در یک پرس‌وجوست و یکی از مهم‌ترین مباحث SQL (و پرتکرارترین سؤال امتحان و مصاحبه). تفاوت انواع آن فقط در یک چیز است: با ردیف‌هایی که جفت ندارند چه می‌کند؟

جدول‌های مثال

دو جدول Customers و Orders داریم. مشتری «رضا» هنوز سفارشی ندارد و سفارش ۱۰۴ به هیچ مشتری وصل نیست (CustomerId آن NULL است):

sql
CREATE TABLE Customers (CustomerId INT PRIMARY KEY, Name NVARCHAR(50));
CREATE TABLE Orders (OrderId INT PRIMARY KEY, CustomerId INT NULL, Amount INT);

INSERT INTO Customers VALUES (1, N'Ali'), (2, N'Sara'), (3, N'Reza');
INSERT INTO Orders VALUES (101, 1, 500), (102, 1, 300), (103, 2, 700), (104, NULL, 900);
Customers: CustomerIdName
1Ali
2Sara
3Reza
Orders: OrderIdCustomerIdAmount
1011500
1021300
1032700
104NULL900

نمای کلی با نمودار

ABINNER JOINABLEFT JOINABRIGHT JOINABFULL JOIN
A = جدول چپ (Customers)، B = جدول راست (Orders). بخش رنگی نشان می‌دهد چه ردیف‌هایی در نتیجه می‌آیند.

INNER JOIN: فقط ردیف‌های مشترک

sql
SELECT c.Name, o.OrderId, o.Amount
FROM Customers c
INNER JOIN Orders o ON o.CustomerId = c.CustomerId;
NameOrderIdAmount
Ali101500
Ali102300
Sara103700

«رضا» (بدون سفارش) و سفارش ۱۰۴ (بدون مشتری) هر دو حذف شده‌اند.

LEFT JOIN: همه‌ی ردیف‌های جدول چپ

sql
SELECT c.Name, o.OrderId, o.Amount
FROM Customers c
LEFT JOIN Orders o ON o.CustomerId = c.CustomerId;
NameOrderIdAmount
Ali101500
Ali102300
Sara103700
RezaNULLNULL

الگوی پرکاربرد: پیدا کردن ردیف‌های بدون جفت. مشتریانی که هیچ سفارشی ندارند:

sql
SELECT c.Name
FROM Customers c
LEFT JOIN Orders o ON o.CustomerId = c.CustomerId
WHERE o.OrderId IS NULL;   -- فقط Reza

RIGHT JOIN: همه‌ی ردیف‌های جدول راست

sql
SELECT c.Name, o.OrderId, o.Amount
FROM Customers c
RIGHT JOIN Orders o ON o.CustomerId = c.CustomerId;
NameOrderIdAmount
Ali101500
Ali102300
Sara103700
NULL104900

RIGHT JOIN دقیقاً همان LEFT JOIN با جابه‌جایی ترتیب جدول‌هاست؛ به همین دلیل در عمل کمتر استفاده می‌شود.

FULL JOIN: همه‌ی ردیف‌های هر دو طرف

sql
SELECT c.Name, o.OrderId, o.Amount
FROM Customers c
FULL JOIN Orders o ON o.CustomerId = c.CustomerId;
NameOrderIdAmount
Ali101500
Ali102300
Sara103700
RezaNULLNULL
NULL104900

CROSS JOIN و SELF JOIN

CROSS JOIN ضرب دکارتی است: هر ردیف جدول اول با تمام ردیف‌های جدول دوم ترکیب می‌شود (۳×۴ = ۱۲ ردیف). برای تولید ترکیب‌ها (مثل همه‌ی سایز و رنگ‌های یک محصول) مفید است.

sql
SELECT c.Name, o.OrderId FROM Customers c CROSS JOIN Orders o;

SELF JOIN یعنی جدول را با خودش JOIN کنی، برای ساختارهای سلسله‌مراتبی مثل کارمند و مدیرش. حتماً به هر نمونه یک Alias متفاوت بده:

sql
SELECT e.FullName AS Employee, m.FullName AS Manager
FROM Employees e
LEFT JOIN Employees m ON m.EmployeeId = e.ManagerId;

جدول مقایسه

نوع JOINردیف‌های بدون جفت چپردیف‌های بدون جفت راستکاربرد
INNERحذفحذففقط داده‌های مرتبط
LEFTنگه‌داری (NULL)حذفهمه‌ی جدول اصلی + اطلاعات اختیاری
RIGHTحذفنگه‌داری (NULL)مثل LEFT با جهت برعکس
FULLنگه‌دارینگه‌داریمقایسه‌ی دو مجموعه
CROSS——ضرب دکارتی / تولید ترکیب

نکته‌هایی که باعث خطا می‌شوند

  • شرط روی جدول راست در WHERE: LEFT JOIN ... WHERE o.Amount > 400 ردیف‌های NULL را حذف می‌کند و عملاً INNER JOIN می‌شود. شرط را در ON بنویس.
  • ردیف‌های تکراری: اگر رابطه یک‌به‌چند باشد، ردیف جدول «یک» به تعداد ردیف‌های «چند» تکرار می‌شود؛ بعد از JOIN، SUM و COUNT را با دقت بنویس.
  • ستون مبهم: اگر دو جدول ستون هم‌نام دارند، همیشه با Alias مشخص کن (c.CustomerId).
  • JOIN روی NULL: NULL = NULL درست نیست؛ ردیف‌هایی که کلید NULL دارند هیچ‌وقت در JOIN جفت نمی‌شوند.

مثال‌ها را در Playground امتحان کن (چون موتور آن SQLite است، حرف N قبل از رشته‌ها را بردار) و درس‌های INNER JOIN و LEFT JOIN را برای تمرین بیشتر ببین.

سوالات متداول درباره‌ی این موضوع

تفاوت INNER JOIN و LEFT JOIN چیست؟

INNER JOIN فقط ردیف‌هایی را برمی‌گرداند که در هر دو جدول جفت دارند؛ LEFT JOIN همه‌ی ردیف‌های جدول چپ را برمی‌گرداند و اگر جفتی در جدول راست نباشد، ستون‌های آن را NULL می‌گذارد.

شرط را در ON بنویسم یا WHERE؟

در INNER JOIN فرقی ندارد، اما در LEFT JOIN شرط روی جدول راست در WHERE ردیف‌های NULL را حذف می‌کند و نتیجه را به INNER JOIN تبدیل می‌کند. شرط‌های مربوط به جدول راست را در ON بگذار.

JOIN بدون شرط ON چه می‌شود؟

اگر از CROSS JOIN استفاده کنی ضرب دکارتی می‌گیری (هر ردیف جدول اول با همه‌ی ردیف‌های جدول دوم). فراموش کردن شرط در JOIN معمولاً به نتیجه‌ی بسیار بزرگ و اشتباه منجر می‌شود.

مصطفی موسویسازنده و نویسنده‌ی SQLFarsi. اگر اشتباهی در مقاله دیدی یا پیشنهادی داری، از طریق mousavi.dev خبر بده.

می‌خوای SQL را از پایه و با تمرین یاد بگیری؟

دوره‌ی رایگان SQLFarsi را با Playground و پروژه‌های واقعی دنبال کن.

شروع یادگیری