نحوه استفاده از Joins در SQL

مقدمه

بسیاری از طراحی های پایگاه داده بر اساس روابط بین نقاط داده خاص، اطلاعات را به جداول مختلف جدا می کنند. حتی در مواردی مانند این، این احتمال وجود دارد که زمان هایی وجود داشته باشد که شخصی بخواهد اطلاعات را از بیش از یک جدول در یک زمان بازیابی کند.

یک راه متداول برای دسترسی به داده ها از چندین جدول در یک عملیات زبان پرس و جو ساختاریافته (SQL) ترکیب جداول با یک بند JOIN است. بر اساس عملیات پیوستن در جبر رابطه‌ای، یک بند JOIN جداول جداگانه را با تطبیق ردیف‌هایی در هر جدول که به یکدیگر مرتبط هستند، ترکیب می‌کند. معمولاً، این رابطه مبتنی بر یک جفت ستون – یکی از هر جدول – است که مقادیر مشترکی دارند، مانند کلید خارجی یک جدول و کلید اصلی جدول دیگری که کلید خارجی به آن ارجاع می‌دهد.

این راهنما نحوه ساخت انواع پرس‌و‌جوهای SQL که شامل یک بند JOIN است را تشریح می‌کند. همچنین انواع مختلف بندهای JOIN، نحوه ترکیب داده‌ها از چندین جداول، و نحوه نام مستعار ستون‌ها را نشان می‌دهد تا نوشتن عملیات JOIN کمتر خسته‌کننده باشد.

پیش نیازها

برای پیروی از این راهنما، به رایانه ای نیاز دارید که دارای نوعی سیستم مدیریت پایگاه داده رابطه ای (RDBMS) است که از SQL استفاده می کند. دستورالعمل ها و مثال های موجود در این راهنما با استفاده از محیط زیر تأیید شدند:

  • سروری که اوبونتو 20.04 را اجرا می کند، با یک کاربر غیر ریشه با امتیازات مدیریتی و یک فایروال پیکربندی شده با UFW
  • MySQL روی سرور نصب و ایمن شده است
  • شما همچنین به یک پایگاه داده با تعدادی جداول بارگذاری شده با داده های نمونه نیاز دارید که می توانید از آنها برای تمرین با استفاده از عملیات JOIN استفاده کنید. ما شما را تشویق می کنیم تا برای جزئیات نحوه اتصال به سرور MySQL و ایجاد پایگاه داده آزمایشی مورد استفاده در نمونه های این راهنما، بخش اتصال به MySQL و راه اندازی یک پایگاه داده نمونه زیر را طی کنید.
اتصال به MySQL و راه اندازی یک پایگاه داده نمونه

اگر سیستم پایگاه داده SQL شما بر روی یک سرور راه دور اجرا می شود، SSH را از دستگاه محلی خود به سرور خود وارد کنید:

ssh sammy@your_server_ip

سپس اعلان سرور MySQL را باز کنید و نام حساب کاربری MySQL خود را جایگزین سامی کنید:

mysql -u sammy -p

یک پایگاه داده به نام joinsDB ایجاد کنید:

CREATE DATABASE joinsDB;

اگر پایگاه داده با موفقیت ایجاد شود، خروجی زیر را دریافت خواهید کرد:

Output
Query OK, 1 row affected (0.01 sec)

برای انتخاب پایگاه داده joinsDB، عبارت USE زیر را اجرا کنید:

USE joinsDB;
Output
Database changed

پس از انتخاب joinsDB، چند جدول درون آن ایجاد کنید. برای مثال‌های مورد استفاده در این راهنما، تصور کنید که کارخانه‌ای را اداره می‌کنید و تصمیم گرفته‌اید اطلاعات مربوط به خط تولید، کارکنان تیم فروش و فروش شرکت‌تان را در پایگاه داده SQL ردیابی کنید. شما قصد دارید با سه جدول شروع کنید که در جدول اول اطلاعات مربوط به محصولات شما ذخیره می شود. شما تصمیم می گیرید که این جدول اول به سه ستون نیاز دارد:

  • شناسه محصول: شماره شناسایی هر محصول که با نوع داده int بیان می شود. این ستون به عنوان کلید اصلی جدول عمل می کند، به این معنی که هر مقدار به عنوان یک شناسه منحصر به فرد برای ردیف مربوطه عمل می کند. از آنجا که هر مقدار در یک کلید اصلی باید منحصر به فرد باشد، این ستون همچنین دارای یک محدودیت UNIQUE برای آن اعمال می شود
  • productName: نام هر محصول با استفاده از نوع داده varchar با حداکثر 20 کاراکتر بیان شده است.
  • قیمت: قیمت هر محصول که با استفاده از نوع داده اعشاری بیان می شود. این عبارت مشخص می کند که هر مقدار در این ستون حداکثر به طول چهار رقم محدود می شود و دو عدد از آن رقم در سمت راست نقطه اعشار قرار دارند. بنابراین، محدوده مقادیر مجاز در این ستون از 99.99- تا 99.99 می رود

جدولی با نام محصولات ایجاد کنید که دارای این سه ستون باشد:

CREATE TABLE products (
productID int UNIQUE,
productName varchar(20),
price decimal (4,2),
PRIMARY KEY (productID)
);

جدول دوم اطلاعات مربوط به کارکنان تیم فروش شرکت شما را ذخیره می کند. شما تصمیم می گیرید که این جدول نیز به سه ستون نیاز دارد:

  • empID: مشابه ستون productID، این ستون یک شماره شناسایی منحصر به فرد برای هر کارمند در تیم فروش دارد که با نوع داده int بیان شده است. به همین ترتیب، این ستون دارای یک محدودیت UNIQUE خواهد بود و به عنوان کلید اصلی جدول تیم عمل می کند.
  • empName: نام هر فروشنده که با استفاده از نوع داده varchar با حداکثر 20 کاراکتر بیان می شود.
  • productSpecialty: به هر یک از اعضای تیم فروش شما یک محصول به عنوان تخصص اختصاص داده شده است. آنها می توانند هر محصولی را که شرکت شما تولید می کند بفروشند، اما تمرکز کلی آنها بر روی هر محصولی است که در آن تخصص دارند. برای نشان دادن این موضوع در جدول، این ستون را ایجاد می کنید که مقدار productID هر محصولی را که هر کارمند در آن تخصص دارد را نگه می دارد.

برای اطمینان از اینکه ستون productSpecialty فقط دارای مقادیری است که شماره شناسه معتبر محصول را نشان می‌دهد، تصمیم می‌گیرید یک محدودیت کلید خارجی برای ستونی اعمال کنید که به ستون productID جدول محصولات اشاره دارد. یک محدودیت کلید خارجی روشی برای بیان رابطه بین دو جدول با الزام این است که مقادیر در ستونی که روی آن اعمال می شود باید در ستونی که به آن ارجاع می دهد وجود داشته باشد. در عبارت CREATE TABLE زیر، محدودیت FOREIGN KEY مستلزم آن است که هر مقداری که به ستون productSpecialty در جدول team اضافه می‌شود باید در ستون productID جدول محصولات وجود داشته باشد.

با این سه ستون جدولی به نام تیم ایجاد کنید:

CREATE TABLE team (
empID int UNIQUE,
empName varchar(20),
productSpecialty int,
PRIMARY KEY (empID),
FOREIGN KEY (productSpecialty) REFERENCES products (productID)
);

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

  • saleID: شبیه به productID و empIDcolumns، این ستون دارای یک شماره شناسایی منحصر به فرد برای هر فروش است که با نوع داده int بیان شده است. این ستون همچنین دارای یک محدودیت UNIQUE است تا بتواند به عنوان کلید اصلی جدول فروش عمل کند
  • مقدار: تعداد واحدهای هر محصول فروخته شده با نوع داده int بیان می شود
  • شناسه محصول: شماره شناسایی محصول فروخته شده به صورت int بیان می شود
  • فروشنده: شماره شناسایی کارمندی که فروش را انجام داده است

مانند ستون productSpecialty از جدول تیم، شما تصمیم می‌گیرید که محدودیت‌های FOREIGN KEY را برای هر دو ستون productID و salesperson اعمال کنید. این اطمینان حاصل می کند که این ستون ها فقط حاوی مقادیری هستند که به ترتیب در ستون productID جدول محصولات و ستون های empID جدول تیم وجود دارند.

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

CREATE TABLE sales (
saleID int UNIQUE,
quantity int,
productID int,
salesperson int,
PRIMARY KEY (saleID),
FOREIGN KEY (productID) REFERENCES products (productID),
FOREIGN KEY (salesperson) REFERENCES team (empID)
);

پس از آن، با اجرای عملیات INSERT INTO زیر، جدول محصولات را با داده های نمونه بارگیری کنید:

INSERT INTO products
VALUES
(1, 'widget', 18.99),
(2, 'gizmo', 14.49),
(3, 'thingamajig', 39.99),
(4, 'doodad', 11.50),
(5, 'whatzit', 29.99);

سپس جدول تیم را با داده های نمونه بارگیری کنید:

INSERT INTO team
VALUES
(1, 'Florence', 1),
(2, 'Mary', 4),
(3, 'Diana', 3),
(4, 'Betty', 2);

جدول فروش را با داده های نمونه نیز بارگیری کنید:

INSERT INTO sales
VALUES
(1, 7, 1, 1),
(2, 10, 5, 4),
(3, 8, 2, 4),
(4, 1, 3, 3),
(5, 5, 1, 3);

در نهایت، تصور کنید که شرکت شما بدون دخالت کسی در تیم فروش شما، چند فروش انجام می دهد. برای ثبت این فروش‌ها، عملیات زیر را اجرا کنید تا سه ردیف به جدول فروش اضافه کنید که مقداری برای ستون فروشنده وجود ندارد:

INSERT INTO sales (saleID, quantity, productID)
VALUES
(6, 1, 5),
(7, 3, 1),
(8, 4, 5);

با این کار، شما آماده هستید تا بقیه راهنما را دنبال کنید و شروع به یادگیری نحوه اتصال جداول به یکدیگر در SQL کنید.

درک نحو عملیات JOIN

بندهای JOIN را می توان در انواع دستورات SQL از جمله عملیات UPDATE و DELETE استفاده کرد. با این حال، برای اهداف تصویری، مثال‌های موجود در این راهنما از پرس‌وجوهای SELECT استفاده می‌کنند تا نحوه عملکرد بندهای JOIN را نشان دهند.

مثال زیر نحو کلی یک عبارت SELECT را نشان می دهد که شامل یک عبارت JOIN است:

SELECT table1.column1, table2.column2
FROM table1 JOIN table2
ON search_condition;

این نحو با یک عبارت SELECT شروع می شود که دو ستون از دو جدول جداگانه را برمی گرداند. توجه داشته باشید که از آنجایی که بندهای JOIN محتویات بیش از یک جدول را با هم مقایسه می‌کنند، این نحو مثالی مشخص می‌کند که هر ستون از کدام جدول انتخاب شود، قبل از نام ستون با نام جدول و نقطه. این به عنوان یک مرجع ستون کاملاً واجد شرایط شناخته می شود.

شما می توانید از ارجاعات ستون کاملاً واجد شرایط مانند اینها در هر عملیاتی استفاده کنید، اما انجام این کار از نظر فنی فقط در عملیاتی ضروری است که دو ستون از جداول مختلف یک نام دارند. با این حال، استفاده از آنها هنگام کار با چندین جدول، تمرین خوبی است، زیرا می توانند به خواندن و درک عملیات JOIN کمک کنند.

بعد از SELECT عبارت FROM می آید. در هر پرس و جو، عبارت FROM جایی است که شما مجموعه داده هایی را که باید جستجو شوند تا داده های مورد نظر را بازگردانید، تعریف می کنید. تنها تفاوت در اینجا این است که عبارت FROM شامل دو جدول است که با کلمه کلیدی JOIN از هم جدا شده اند. یک راه مفید برای فکر کردن به نوشتن پرس‌و‌جوها این است که به خاطر داشته باشید که ستون‌هایی را انتخاب کنید که از کدام جدولی که می‌خواهید پرس‌وجو کنید، بازگردانده شوند.

پس از آن یک عبارت ON وجود دارد که توضیح می دهد چگونه پرس و جو باید دو جدول را با تعریف یک شرط جستجو به هم بپیوندد. شرط جستجو مجموعه‌ای از یک یا چند گزاره یا عبارت است که می‌تواند «درست»، «نادرست» یا «ناشناخته» بودن یک شرط خاص را ارزیابی کند. این می تواند مفید باشد که عملیات JOIN را به عنوان ترکیب هر سطر از هر دو جدول و سپس برگرداندن هر ردیفی که شرط جستجو در عبارت ON برای آنها “درست” ارزیابی می شود، مفید باشد.

در یک عبارت ON، معمولاً منطقی است که یک شرط جستجو را شامل شود که آزمایش کند آیا دو ستون مرتبط – مانند کلید خارجی یک جدول و کلید اصلی جدول دیگری که کلید خارجی به آن ارجاع می دهد – دارای مقادیر برابر هستند یا خیر. این گاهی اوقات به عنوان یک equi join نامیده می شود.

به عنوان مثالی از نحوه پیوستن equi به داده های منطبق از چندین جدول، پرس و جو زیر را با استفاده از داده های نمونه ای که قبلا اضافه کرده اید اجرا کنید. این عبارت به جداول محصولات و تیم با یک شرط جستجو می پیوندد که مقادیر تطبیق را در ستون های productID و productSpecialty مربوطه آنها آزمایش می کند. سپس نام هر یک از اعضای تیم فروش، نام هر محصولی که در آن تخصص دارند و قیمت آن محصولات را برمی گرداند:

SELECT team.empName, products.productName, products.price
FROM products JOIN team
ON products.productID = team.productSpecialty

در اینجا مجموعه نتایج این پرس و جو است:

Output
+----------+-------------+-------+
| empName | productName | price |
+----------+-------------+-------+
| Florence | widget | 18.99 |
| Mary | doodad | 11.50 |
| Diana | thingamajig | 39.99 |
| Betty | gizmo | 14.49 |
+----------+-------------+-------+
4 rows in set (0.00 sec)

برای نشان دادن اینکه چگونه SQL این جداول را برای تشکیل این مجموعه نتیجه ترکیب می‌کند، اجازه دهید نگاهی دقیق‌تر به این فرآیند بیندازیم. برای روشن بودن، موارد زیر دقیقاً آن چیزی نیست که یک سیستم مدیریت پایگاه داده دو جدول را به هم متصل می کند، اما می تواند مفید باشد که عملیات JOIN را مانند رویه ای در نظر بگیرید.

ابتدا، پرس و جو هر سطر و ستون در جدول اول در عبارت FROM، محصولات را چاپ می کند:

JOIN Process Example
+-----------+-------------+-------+
| productID | productName | price |
+-----------+-------------+-------+
| 1 | widget | 18.99 |
| 2 | gizmo | 14.49 |
| 3 | thingamajig | 39.99 |
| 4 | doodad | 11.50 |
| 5 | whatzit | 29.99 |
+-----------+-------------+-------+
سپس، به هر یک از این ردیف‌ها نگاه می‌کند و با هر ردیفی از جدول تیم که productSpecialty آن برابر با مقدار productID در آن سطر است، مطابقت می‌دهد:
JOIN Process Example
+-----------+-------------+-------+-------+----------+------------------+
| productID | productName | price | empID | empName | productSpecialty |
+-----------+-------------+-------+-------+----------+------------------+
| 1 | widget | 18.99 | 1 | Florence | 1 |
| 2 | gizmo | 14.49 | 4 | Betty | 2 |
| 3 | thingamajig | 39.99 | 3 | Diana | 3 |
| 4 | doodad | 11.50 | 2 | Mary | 4 |
| 5 | whatzit | 29.99 | | | |
+-----------+-------------+-------+-------+----------+------------------+
سپس، سطرهایی را که مطابقت ندارند را برش می‌دهد و ستون‌ها را بر اساس ترتیب آنها در عبارت SELECT مرتب می‌کند، ستون‌هایی را که مشخص نشده بودند حذف می‌کند، ردیف‌ها را متوسل می‌کند و مجموعه نتایج نهایی را برمی‌گرداند:
JOIN Process Example
+----------+-------------+-------+
| empName | productName | price |
+----------+-------------+-------+
| Florence | widget | 18.99 |
| Mary | doodad | 11.50 |
| Diana | thingamajig | 39.99 |
| Betty | gizmo | 14.49 |
+----------+-------------+-------+
4 rows in set (0.00 sec)

استفاده از اتصالات equi رایج ترین راه برای پیوستن به جداول است، اما می توان از سایر عملگرهای SQL مانند <، >، LIKE، NOT LIKE یا حتی BETWEEN در شرایط جستجوی عبارت ON استفاده کرد. اما توجه داشته باشید که استفاده از شرایط جستجوی پیچیده‌تر می‌تواند پیش‌بینی اینکه چه داده‌هایی در مجموعه نتایج ظاهر می‌شوند را دشوار می‌کند.

در بیشتر پیاده‌سازی‌ها، می‌توانید جدول‌ها را با هر مجموعه‌ای از ستون‌ها که دارای آنچه استاندارد SQL به عنوان نوع داده «JOIN واجد شرایط» نامیده می‌شود، بپیوندید. این به این معنی است که به طور کلی، می‌توان ستونی را که داده‌های عددی را در خود نگه می‌دارد، به هر ستون دیگری که داده‌های عددی را در خود نگه می‌دارد، بدون در نظر گرفتن انواع داده‌های مربوطه، ملحق کرد. به همین ترتیب، معمولاً می توان هر ستونی را که دارای مقادیر کاراکتر است به هر ستون دیگری که داده کاراکتر را در خود نگه می دارد، ملحق کرد. همانطور که قبلاً گفته شد، ستون‌هایی که برای پیوستن به دو جدول مطابقت می‌دهید، معمولاً ستون‌هایی هستند که نشان‌دهنده رابطه بین جداول هستند، مانند یک کلید خارجی و کلید اصلی جدول دیگری که به آن ارجاع می‌دهد.

بسیاری از پیاده‌سازی‌های SQL به شما اجازه می‌دهند به ستون‌هایی بپیوندید که نام یکسانی دارند با کلمه کلیدی USING به جای ON. نحو چنین عملیاتی ممکن است به این صورت باشد:

SELECT table1.column1, table2.column2
FROM table1 JOIN table2
USING (related_column);

در این نحو مثال، عبارت USING معادل ON table1.related_column = table2.related_column; است.

از آنجایی که فروش و محصولات هر کدام ستونی به نام productID دارند، می توانید با تطبیق این ستون ها با کلمه کلیدی USING به آنها بپیوندید. دستور زیر این کار را انجام می دهد و saleID هر فروش، تعداد واحدهای فروخته شده، نام هر محصول فروخته شده و قیمت آن را برمی گرداند. همچنین، مجموعه نتایج را بر اساس مقدار saleID به ترتیب صعودی مرتب می‌کند:

SELECT sales.saleID, sales.quantity, products.productName, products.price
FROM sales JOIN products
USING (productID)
ORDER BY saleID;
Output
+--------+----------+-------------+-------+
| saleID | quantity | productName | price |
+--------+----------+-------------+-------+
| 1 | 7 | widget | 18.99 |
| 2 | 10 | whatzit | 29.99 |
| 3 | 8 | gizmo | 14.49 |
| 4 | 1 | thingamajig | 39.99 |
| 5 | 5 | widget | 18.99 |
| 6 | 1 | whatzit | 29.99 |
| 7 | 3 | widget | 18.99 |
| 8 | 4 | whatzit | 29.99 |
+--------+----------+-------------+-------+
8 rows in set (0.00 sec)

هنگام پیوستن به جداول، سیستم پایگاه داده گاهی اوقات ردیف‌ها را به گونه‌ای تنظیم می‌کند که پیش‌بینی آسان نیست. گنجاندن عبارت ORDER BY مانند این می‌تواند به منسجم‌تر و خواندنی‌تر کردن مجموعه‌های نتایج کمک کند.

پیوستن به بیش از دو جدول

ممکن است زمان هایی وجود داشته باشد که شما نیاز به ترکیب داده های بیش از دو جدول داشته باشید. شما می توانید هر تعداد جدول را با جاسازی بندهای JOIN در سایر بندهای JOIN به یکدیگر بپیوندید. سینتکس زیر نمونه ای از این است که هنگام پیوستن به سه جدول چگونه به نظر می رسد:

SELECT table1.column1, table2.column2, table3.column3
FROM table1 JOIN table2
ON table1.related_column = table2.related_column
JOIN table3
ON table3.related_column = table1_or_2.related_column;

عبارت FROM این مثال دستوری با پیوستن به جدول 1 با جدول 2 شروع می شود. پس از این بند ON پیوستن، یک JOIN دوم را شروع می کند که مجموعه اولیه جداول به هم پیوسته را با جدول 3 ترکیب می کند. توجه داشته باشید که جدول سوم را می توان به ستونی در جدول اول یا دوم متصل کرد.

برای مثال، تصور کنید که می خواهید بدانید فروش کارمندتان چقدر درآمد داشته است، اما فقط به سوابق فروش اهمیت می دهید که شامل فروش محصولی است که کارمند در آن تخصص دارد.

برای به دست آوردن این اطلاعات، می توانید کوئری زیر را اجرا کنید. این پرس و جو با پیوستن جداول محصولات و فروش به یکدیگر با تطبیق ستون های productID مربوطه آنها شروع می شود. سپس جدول تیم را با تطبیق هر ردیف در JOIN اولیه به ستون productSpecialty خود به دو جدول اول می‌پیوندد. سپس پرس و جو نتایج را با یک بند WHERE فیلتر می کند تا فقط ردیف هایی را که کارمند مطابقت داده شده نیز شخصی است که فروش را انجام داده است برمی گرداند. این پرس و جو همچنین شامل یک عبارت ORDER BY است که نتایج نهایی را به ترتیب صعودی بر اساس مقدار در ستون saleID مرتب می کند:

SELECT sales.saleID,
team.empName,
products.productName,
(sales.quantity * products.price)
FROM products JOIN sales
USING (productID)
JOIN team
ON team.productSpecialty = sales.productID
WHERE team.empID = sales.salesperson
ORDER BY sales.saleID;
توجه داشته باشید که در میان ستون‌های فهرست شده در عبارت SELECT عبارتی وجود دارد که مقادیر موجود در ستون مقدار جدول فروش را در مقادیر قیمت جدول محصولات ضرب می‌کند. محصولات این مقادیر را در ردیف‌های همسان برمی‌گرداند:
Output
+--------+----------+-------------+-----------------------------------+
| saleID | empName | productName | (sales.quantity * products.price) |
+--------+----------+-------------+-----------------------------------+
| 1 | Florence | widget | 132.93 |
| 3 | Betty | gizmo | 115.92 |
| 4 | Diana | thingamajig | 39.99 |
+--------+----------+-------------+-----------------------------------+
3 rows in set (0.00 sec)

همه نمونه‌ها تا کنون دارای یک نوع عبارت JOIN هستند: JOIN داخلی. برای مروری بر پیوست‌های داخلی، پیوستن‌های بیرونی و تفاوت آن‌ها، به خواندن بخش بعدی ادامه دهید.

عملیات JOIN داخلی در مقابل بیرونی

دو نوع اصلی از جمله های JOIN وجود دارد: اتصالات داخلی و اتصالات OUTER. تفاوت بین این دو نوع اتصال به داده هایی است که آنها برمی گردند. عملیات پیوستن داخلی فقط ردیف‌های منطبق را از هر جدول متصل برمی‌گرداند، در حالی که اتصالات OUTER هر دو ردیف منطبق و غیر منطبق را برمی‌گردانند.

سینتکس‌ها و پرس‌و‌جوهای نمونه از بخش‌های قبلی، همگی از عبارت‌های INNER JOIN استفاده می‌کنند، حتی اگر هیچ‌کدام از آنها شامل کلمه کلیدی INNER نباشد. اکثر پیاده سازی های SQL هر عبارت JOIN را به عنوان یک پیوستن INNER در نظر می گیرند، مگر اینکه به صراحت خلاف آن ذکر شده باشد.

کوئری هایی که یک JOIN بیرونی را مشخص می کنند چندین جدول را ترکیب می کنند و هر ردیفی را که مطابقت دارند و همچنین ردیف هایی که مطابقت ندارند را برمی گرداند. این می تواند برای یافتن ردیف هایی با مقادیر گمشده یا در مواردی که تطابق جزئی قابل قبول است مفید باشد.

عملیات اتصال بیرونی را می توان به سه نوع تقسیم کرد: اتصالات LEFT OUTER، اتصالات OUTER RIGHT و اتصالات FULL OUTER. اتصالات LEFT OUTER، یا فقط پیوستن به چپ، هر ردیف منطبق از دو جدول به هم پیوسته، و همچنین هر ردیف غیر منطبق از جدول “چپ” را برمی گرداند. در زمینه عملیات JOIN، جدول “چپ” همیشه اولین جدولی است که بلافاصله بعد از کلمه کلیدی FROM و در سمت چپ کلمه کلیدی JOIN مشخص می شود. به همین ترتیب، جدول «راست» دومین جدول یا همان جدولی است که بلافاصله بعد از JOIN می‌آید، و پیوستن RIGHT OUTER هر ردیف منطبق از جداول به هم پیوسته را به همراه هر سطر غیر منطبق از جدول «راست» برمی‌گرداند. FULL OUTER JOIN هر سطر را از هر دو جدول، از جمله سطرهایی از هر یک از جدول‌ها که مطابقت ندارند، برمی‌گرداند.

برای نشان دادن اینکه چگونه این انواع مختلف بند JOIN داده ها را برمی گرداند، پرس و جوهای مثال زیر را روی جداول ایجاد شده در بخش فرعی اتصال به و راه اندازی یک پایگاه داده نمونه قبلی اجرا کنید. این پرس و جوها یکسان هستند با این تفاوت که هر کدام نوع متفاوتی از عبارت JOIN را مشخص می کنند.

این مثال اول از یک JOIN داخلی برای ترکیب جداول فروش و تیم با تطبیق ستون‌های فروشنده و empID مربوطه استفاده می‌کند. باز هم، کلمه کلیدی INNER ضمنی است حتی اگر به صراحت در آن گنجانده نشده باشد:

SELECT sales.saleID, sales.quantity, sales.salesperson, team.empName 
FROM sales JOIN team
ON sales.salesperson = team.empID;
از آنجایی که این کوئری از یک عبارت JOIN داخلی استفاده می کند، فقط ردیف های منطبق را از هر دو جدول برمی گرداند:
Output
+--------+----------+-------------+----------+
| saleID | quantity | salesperson | empName |
+--------+----------+-------------+----------+
| 1 | 7 | 1 | Florence |
| 4 | 1 | 3 | Diana |
| 5 | 5 | 3 | Diana |
| 2 | 10 | 4 | Betty |
| 3 | 8 | 4 | Betty |
+--------+----------+-------------+----------+
5 rows in set (0.00 sec)
این نسخه از کوئری به جای آن از یک عبارت LEFT OUTER JOIN استفاده می کند:
SELECT sales.saleID, sales.quantity, sales.salesperson, team.empName
FROM sales LEFT OUTER JOIN team
ON sales.salesperson = team.empID;
مانند کوئری قبلی، این مورد نیز هر مقدار منطبق را از هر دو جدول برمی گرداند. با این حال، هر مقدار را از جدول «سمت چپ» (در این مورد، فروش) که در جدول «راست» (تیم) مطابقت ندارد، برمی‌گرداند. از آنجایی که این سطرها در جدول سمت چپ دارای منطبق در سمت راست نیستند، مقادیر نامتناسب به صورت NULL برگردانده می شوند:
Output
+--------+----------+-------------+----------+
| saleID | quantity | salesperson | empName |
+--------+----------+-------------+----------+
| 1 | 7 | 1 | Florence |
| 2 | 10 | 4 | Betty |
| 3 | 8 | 4 | Betty |
| 4 | 1 | 3 | Diana |
| 5 | 5 | 3 | Diana |
| 6 | 1 | NULL | NULL |
| 7 | 3 | NULL | NULL |
| 8 | 4 | NULL | NULL |
+--------+----------+-------------+----------+
8 rows in set (0.00 sec)
این نسخه بعدی پرس و جو در عوض از یک عبارت RIGHT JOIN استفاده می کند:
SELECT sales.saleID, sales.quantity, sales.salesperson, team.empName
FROM sales RIGHT JOIN team
ON sales.salesperson = team.empID;

توجه داشته باشید که عبارت JOIN این کوئری به جای RIGHT OUTER JOIN، RIGHT JOIN را می خواند. همانطور که کلمه کلیدی INNER برای تعیین یک بند INNER JOIN لازم نیست، OUTER هر زمان که شما LEFT JOIN یا RIGHT JOIN را می نویسید، به طور ضمنی معنا می شود.

نتیجه این پرس و جو برعکس مورد قبلی است، زیرا هر سطر را از هر دو جدول برمی گرداند، اما فقط سطرهای بی همتا را از جدول “راست” برمی گرداند:

Output
+--------+----------+-------------+----------+
| saleID | quantity | salesperson | empName |
+--------+----------+-------------+----------+
| 1 | 7 | 1 | Florence |
| NULL | NULL | NULL | Mary |
| 4 | 1 | 3 | Diana |
| 5 | 5 | 3 | Diana |
| 2 | 10 | 4 | Betty |
| 3 | 8 | 4 | Betty |
+--------+----------+-------------+----------+
6 rows in set (0.00 sec)

نام مستعار جدول و ستون در بندهای JOIN

هنگام پیوستن به جداول با نام های طولانی یا بسیار توصیفی، نوشتن چندین مرجع ستون کاملاً واجد شرایط ممکن است خسته کننده شود. برای جلوگیری از این امر، کاربران گاهی اوقات ارائه نام جدول یا ستون با نام مستعار کوتاه‌تر را مفید می‌دانند.

می توانید این کار را در SQL با دنبال کردن هر تعریف جدول در عبارت FROM با کلمه کلیدی AS انجام دهید و سپس آن را با نام مستعار انتخابی خود دنبال کنید:

SELECT t1.column1, t2.column2
FROM table1 AS t1 JOIN table2 AS t2
ON t1.related_column = t2.related_column;

این نحو مثال از نام مستعار در عبارت SELECT استفاده می کند، حتی اگر آنها تا قبل از عبارت FROM تعریف نشده باشند. این امکان پذیر است زیرا در پرس و جوهای SQL، ترتیب اجرا با عبارت FROM شروع می شود. این می تواند گیج کننده باشد، اما یادآوری این موضوع و فکر کردن به نام مستعار قبل از شروع نوشتن پرس و جو مفید است.

به عنوان مثال، کوئری زیر را اجرا کنید که به جداول فروش و محصولات می پیوندد و به ترتیب نام مستعار S و P را در اختیار آنها قرار می دهد:

SELECT S.saleID, S.quantity,
P.productName,
(P.price * S.quantity) AS revenue 
FROM sales AS S JOIN products AS P
USING (productID);
توجه داشته باشید که این مثال یک نام مستعار سوم، درآمد، برای حاصل ضرب مقادیر در ستون مقدار جدول فروش و مقادیر تطبیق آنها از ستون قیمت جدول محصولات ایجاد می کند. این فقط در نام ستون در مجموعه نتایج مشهود است، اما ارائه نام مستعار مانند این می تواند برای انتقال معنی یا هدف در پشت نتایج پرس و جو مفید باشد:
Output
+--------+----------+-------------+---------+
| saleID | quantity | productName | revenue |
+--------+----------+-------------+---------+
| 1 | 7 | widget | 132.93 |
| 2 | 10 | whatzit | 299.90 |
| 3 | 8 | gizmo | 115.92 |
| 4 | 1 | thingamajig | 39.99 |
| 5 | 5 | widget | 94.95 |
| 6 | 1 | whatzit | 29.99 |
| 7 | 3 | widget | 56.97 |
| 8 | 4 | whatzit | 119.96 |
+--------+----------+-------------+---------+
8 rows in set (0.00 sec)
توجه داشته باشید که هنگام تعریف نام مستعار، کلمه کلیدی AS از نظر فنی اختیاری است. مثال قبلی را نیز می توان اینگونه نوشت:
SELECT S.saleID, S.quantity, P.productName, (P.price * S.quantity) revenue 
FROM sales S JOIN products P
USING (productID);

حتی اگر کلمه کلیدی AS برای تعریف نام مستعار مورد نیاز نیست، گنجاندن آن روش خوبی در نظر گرفته می شود. انجام این کار می تواند به روشن نگه داشتن هدف پرس و جو و بهبود خوانایی آن کمک کند.

نتیجه

با خواندن این راهنما، یاد گرفتید که چگونه از عملیات JOIN برای ترکیب جداول جداگانه در یک مجموعه نتایج پرس و جو استفاده کنید. در حالی که دستورات نشان داده شده در اینجا باید روی اکثر پایگاه داده های رابطه ای کار کنند، توجه داشته باشید که هر پایگاه داده SQL از پیاده سازی منحصر به فرد خود از زبان استفاده می کند. برای توضیح کامل تر هر فرمان و مجموعه کامل گزینه های آنها باید به اسناد رسمی DBMS خود مراجعه کنید.

[تعداد: 1   میانگین: 5/5]
دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

شاید دوست داشته باشید