Key Takeaways
- MySQL joins allow you to combine data from multiple tables into a single, organized result set.
- Each join type (INNER, LEFT, RIGHT, FULL, and more) controls which matching or non-matching rows appear in the final query output.
- Joins are fundamental for efficiently retrieving and analyzing related data in any relational database application.
Learning how to join two tables in MySQL is one of the most essential skills for anyone working with relational databases. Almost every real-world query requires pulling data from more than one table, and MySQL joins are the mechanism that makes it possible to do that cleanly in a single query.
For example, joining a “customers” table with an “orders” table lets you retrieve order details alongside customer information at once, rather than running separate queries and combining results manually.
This guide covers every method to join two tables in MySQL, how to extend those joins to multiple tables, and when to use each join type.
Let’s get started.
Cloudways Performance Bootcamp · Free · Mar 10–11
From CDN to Core Web Vitals, watch experts fix real WordPress performance issues, live.
What Are Joins in MySQL?
In short, MySQL Joins lets you access data from multiple tables. A MySQL Join is performed whenever two or more tables are joined in an SQL statement.
The basic format of an SQL join statement looks like this:
SELECT * FROM <first_table> <join_type> <second_table> <join_condition>;
Database Joins merge records from different sources based on matching values in specific columns. Each resulting row includes data from the first table and data from the second table, aligned based on shared column values.
In a join, each row includes all columns from the first table, followed by all columns from the second table. You can specify which columns to display in the SELECT part of the query.
MySQL Joins include:
- MySQL Inner Join (also known as the Simple Join)
- MySQL Left Outer Join (also called the Left Join, it returns matching records from the left table)
- Right Join (this returns the matching records from the right table)
- Full Join (this returns matching records from all tables)
The type of join and the conditions specified determine how each resulting row is constructed and what happens to rows from each table that don’t match the join condition.
For instance, an Inner Join can be used to combine a “customers” table with an “orders” table, retrieving orders alongside corresponding customer information.
How to Join Two Tables in MySQL
The core pattern for joining two tables in MySQL is straightforward. Use the JOIN keyword with an ON clause that specifies the matching condition between the two tables.
Here is the general syntax to MySQL join two tables:
SELECT column_name(s) FROM table1 JOIN table2 ON table1.column_name = table2.column_name;
For example, to combine a “customers” table with an “orders” table on a shared customer ID:
SELECT customers.customer_name, orders.order_id, orders.order_date FROM customers INNER JOIN orders ON customers.customer_id = orders.customer_id;
How to Join Multiple Tables in MySQL?
If you are working on a large application, such as an e-commerce store, and creating multiple tables in it, such as customers, orders, and products, you may need to join tables.
Let’s look at an example where we’ll get all the products ordered by specific customers.
Let’s create our query:
SELECT * FROM table1 LEFT JOIN table2 ON table2.id = table1.id LEFT JOIN table3 ON table3.id = table1.id
If you look at the query above, we first join Table 1 and Table 2, which delivers a temporary table with combined data from Table 1 and Table 2, which is then joined to Table 3. This equation can be extended to more than 3 tables to N tables. You need to make sure that the SQL query has an N-1 join statement in order to join N tables.
The above query will allow you to match the rows from Table 1 (in any case) to the rows of the other two tables. Using LEFT JOIN allows you to join Table 2 and Table 3 with Table 1 (not only Table 2 with Table 1 and Table 3 with Table 2).
You can also add conditions like WHERE, AND, and ORDER BY:
SELECT * FROM table1 LEFT JOIN table2 ON table2.id = table1.id LEFT JOIN table3 ON table3.id = table1.id WHERE month = 'numberHere' AND (table2.email IS NOT NULL OR table3.email IS NOT NULL) ORDER BY submitdate DESC
How Many Tables Can Be Joined in MySQL?
According to the official documentation of MySQL 8.0, the maximum number of tables in a JOIN statement is 61. However, note that JOIN statements could require a lot of server resources as the number of tables increases. If this is the case with your query, I highly recommend breaking it into multiple queries to reduce the load on the server.
Types of Joins in MySQL
There are different types of joins, and each one can produce different data sets. Knowing how they work can help you select the most suitable join to achieve the desired data outcome for your query.
- Inner Join
- Right Join
- Left Join
- Union
- Cross Join or Cartesian Product
- Self Join
- Full Outer Join
- Natural Join
Host PHP Websites with Ease [Starts at $11 Credit]
- Free Staging
- Free backup
- PHP 8.4
- Unlimited Websites

To demonstrate the behavior of each join type, let’s consider a scenario where we have two tables: myguests and messages.
Schema for the “messages” Table
We’ll create a table named “messages” to store messages along with the user ID of the sender. Here’s the schema for our table:
CREATE TABLE `messages` ( `id` int(11) NOT NULL, `message` varchar(255) NOT NULL );
This table will serve as our reference for testing each join type.
Inner Join
In MySQL, the default type of join is an inner join. This can be specified using either INNER JOIN or just JOIN. Additionally, MySQL supports CROSS JOIN. Unlike certain database systems, where INNER JOIN and CROSS JOIN are separate concepts, MySQL combines them into a single construct.
The structure of Inner Join queries are:
SELECT column_name(s) FROM table1 INNER JOIN table2 ON table1.column_name=table2.column_name;
Inner Join and simple Join are the same. You can also write your query like this:
SELECT column_name(s) FROM table1 JOIN table2 ON table1.column_name=table2.column_name;
Now let us fetch the Name and the message from our database using Inner join. The query will look something like this:
$sql = "SELECT CONCAT(myguests.firstname,' ',myguests.lastname) AS name, myguests.email, messages.message From myguests INNER JOIN messages ON myguests.id = messages.id";
The CONCAT function is used to join two string columns in MySQL. Now open your index.php, which we have created previously, and copy the following code in it.
<table>
<tr>
<td> Name</td>
<td> Email</td>
<td> Message</td>
<!-- <td> Message</td>
<td> Date</td>!-->
</tr>
<?php
include 'crud.php';
$sql = "SELECT CONCAT(myguests.firstname,' ',myguests.lastname) AS name, myguests.email, messages.message
From myguests
INNER JOIN messages
ON myguests.id = messages.id";
$result = selectdata($sql);
if($result != "zero")
{
while($row = $result->fetch_assoc())
{
echo "<tr>";
echo "<td>" . $row['name'] . "</td>";
echo "<td>" . $row['email'] . "</td>";
if($row['message'] === null){echo "<td>" . 'null'. "</td>";} else { echo "<td>" . $row['message']. "</td>"; } ;
echo "</tr>";
}
}
else
{
echo $result;
}
?>
</table>
?>
When you run this page on your PHP web hosting server, your result will look like this:
As you can clearly see, it has returned only those results that match user_id and where messages are not null.
RIGHT JOIN
RIGHT JOIN combines tables to return all values from the right table and matched values from the left table. It also includes NULL values on the left table when no match is found.
The structure for RIGHT JOIN is:
SELECT column_name(s) FROM table1 RIGHT JOIN table2 ON table1.column_name=table2.column_name;
Suppose we want to fetch the Name and message from our database, with messages as the right table and myguests as the left table. The query would be:
$sql = "SELECT CONCAT(myguests.firstname,' ',myguests.lastname) AS name, myguests.email, messages.message From myguests RIGHT JOIN messages ON messages.id = myguests.id";
This query returns all messages from the messages table. For each message, it also fetches the corresponding names and emails from the myguests table if available. If there are no matching IDs in the myguests table, NULL values are returned for names and emails.
Now open index.php and replace $sql query with the above. When you run it, your result will be:
If you take a look at the messages table in the screenshot above, you’ll notice some IDs that don’t match any user IDs. That’s why this query returns null in the name and email columns where it doesn’t find any matches in the left column.
LEFT JOIN
LEFT JOINs join the two tables in such a way that they return all the values from the left and matched values from the right tables, and also return NULL on the right table when there is no match found. The structure for a LEFT JOIN is:
SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.column_name=table2.column_name;
Now let’s retrieve the Name and the message from our database, with the ‘messages’ table as our right table and ‘myguests’ as our left table.
$sql = "SELECT CONCAT(myguests.firstname,' ',myguests.lastname) AS name, myguests.email, messages.message From myguests LEFT JOIN messages ON messages.id = myguests.id";
Now open index.php and replace the $sql query with the above. When you run it, your result will be:
If you look at the messages table, you will find some IDs that don’t match any user IDs. That’s why this query returns NULL in the Message column, and it doesn’t find any match in the right column.
UNION
UNION in MySQL combines multiple columns from different tables into a single result set. The structure of a UNION query for selecting unique values is:
SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2;
And for selecting repeated values from columns:
SELECT column_name(s) FROM table1 UNION ALL SELECT column_name(s) FROM table2;
Now, let us fetch the IDs from our tables.
$sql = "SELECT id FROM myguests UNION SELECT id FROM messages";
Now open index.php and replace the $sql query with the one above. When you run it, your result will be:
The query has fetched all the unique IDs found in both tables.
Cross JOIN or Cartesian Product
This type of JOIN returns the cartesian product of rows from the tables in Join. It will return a table that consists of records that combine each row from the first table with each row of the second table.
Cross JOIN Syntax is:
SELECT column-name-list from table-name1 CROSS JOIN table-name2;
Now, let’s show Cross JOIN using the “myguests” and “messages” tables:
Suppose we want to list all possible combinations of names from the “myguests” table with messages from the “messages” table. We can do this using a Cross JOIN:
SELECT myguests.firstname, myguests.lastname, messages.message FROM myguests CROSS JOIN messages;
This query will give us a list with every combination of a name from the “myguests” table and a message from the “messages” table.
Self JOIN
A Self Join is a type of join that combines the rows of a table with itself. While it may not be immediately apparent how this could be useful, it actually has many common applications.
Self Join Syntax:
SELECT column_name(s) FROM table1 T1, table1 T2 WHERE condition;
Now, let’s demonstrate a Self Join using the “messages” table:
Suppose we want to find pairs of messages that have the same sender. We can achieve this using a Self Join:
SELECT m1.id, m1.sender, m2.id, m2.sender FROM messages m1, messages m2 WHERE m1.sender = m2.sender AND m1.id <> m2.id;
This query will return pairs of messages with the same sender, excluding cases where a message is compared with itself.
Self Joins are particularly useful in scenarios where you need to compare rows within the same table, such as in hierarchical structures or when dealing with recursive relationships.
FULL OUTER JOIN
The FULL OUTER JOIN returns all records when there is a match in either the left (table1) or right (table2) table records. It essentially combines the results of both LEFT JOIN and RIGHT JOIN.
Note: FULL OUTER JOIN can potentially return very large result sets!
Full Outer Join Syntax:
SELECT column_name(s) FROM table1 FULL OUTER JOIN table2 ON table1.column_name = table2.column_name;
Here’s a brief example to illustrate FULL OUTER JOIN:
Suppose we have two tables, “employees” and “departments”, and we want to retrieve all records from both tables, including matching records and unmatched records:
SELECT e.employee_id, e.employee_name, d.department_name FROM employees e FULL OUTER JOIN departments d ON e.department_id = d.department_id;
This query will return all team member records, including those without a corresponding department, and all department records, including those without any associated employees.
NATURAL JOIN
Natural Join is a type of join in SQL that combines rows from tables based on columns with the same name and data type. This join only includes common columns once in the result set.
To use Natural Join, you can combine two or more tables using the following syntax:
SELECT column_1, column_2, ..., column_n FROM table_1 NATURAL JOIN table_2;
Let’s illustrate Natural Join using the “messages” table:
Imagine we have two tables, “messages” and “users”, both containing a column named “user_id”. We aim to fetch all records from both tables where the “user_id” column values match:
SELECT * FROM messages NATURAL JOIN users;
This query will execute a Natural Join on the “user_id” column, merging rows from both tables where the “user_id” values match. The resulting dataset will feature the “user_id” column only once.
Summary
MySQL joins are the foundation of relational data retrieval. Almost every real-world database query involves combining data from more than one table, and choosing the right join type determines exactly which rows appear in your result.
Here is a quick reference:
| Join Type | What It Returns |
|---|---|
| INNER JOIN | Only rows with matches in both tables |
| LEFT JOIN | All rows from the left table, matched rows from the right, NULL where no match |
| RIGHT JOIN | All rows from the right table, matched rows from the left, NULL where no match |
| FULL OUTER JOIN | All rows from both tables, NULL where no match on either side |
| CROSS JOIN | Every combination of rows from both tables |
| SELF JOIN | Rows from a table joined with itself |
| UNION | Combined rows from two queries stacked vertically, duplicates removed |
| NATURAL JOIN | Rows joined automatically on columns with the same name and data type |
Q. How Do You Join Two Tables in MySQL?
A. To join two tables in MySQL, use the JOIN clause with the ON keyword to specify the matching condition between the two tables. The most common approach is INNER JOIN, which returns only rows where a match exists in both tables:
SELECT orders.order_id, customers.customer_name FROM orders INNER JOIN customers ON orders.customer_id = customers.customer_id;
For rows that do not have a match, use LEFT JOIN or RIGHT JOIN depending on which table you want to preserve fully.
Q. How Do You Join Two Databases in MySQL?
A. Reference tables from two different databases using the database_name.table_name format in your JOIN statement:
SELECT tb_1.*, tb_2.* FROM database_1.table_name_1 tb_1 JOIN database_2.table_name_2 tb_2 ON tb_1.id = tb_2.id;
Q. How Do You MySQL Join Tables With a Many-to-Many Relationship?
A. Use a junction table that holds foreign keys from both tables, then join through it:
SELECT e.event_name, p.participant_name FROM events e JOIN event_participants ep ON e.id = ep.event_id JOIN participants p ON ep.participant_id = p.id;
Q. Can You MySQL Combine Two Tables Without a Shared Column?
A. Yes. Use CROSS JOIN to pair every row from one table with every row from the other, or UNION to stack results from two SELECT queries vertically. Neither requires a shared key or relationship.
Q. Can You Join Two MySQL Tables With the Same Column Names?
A. Yes. Use table aliases to distinguish between columns with the same name and avoid ambiguity:
SELECT t1.column_name AS t1_column, t2.column_name AS t2_column FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id;
Q. How Do You Join 3 Tables in MySQL?
A. Chain multiple JOIN statements. Each additional table requires one additional JOIN:
SELECT t1.column1, t2.column2, t3.column3 FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id JOIN table3 t3 ON t2.id = t3.id;
Q. How Do You Join Two Tables in MySQL Without the JOIN Keyword?
A. List both tables in the FROM clause separated by a comma. This is called an implicit join:
SELECT * FROM TableA a, TableB b WHERE a.id = b.id;
This works but explicit JOIN statements are preferred for clarity and performance.
Q. Is JOIN the Same as INNER JOIN in MySQL?
A. Yes. In MySQL, JOIN and INNER JOIN are identical. Both return only the rows where matching values exist in both tables.
Q. How Do You Merge Two Tables in MySQL Using UNION?
A. Use the UNION operator to stack rows from both tables into one result set. Both tables must have the same number of columns with compatible data types:
SELECT * FROM table1 UNION SELECT * FROM table2;
Use UNION ALL instead of UNION if you want to include duplicate rows in the result.
Shahzeb Ahmed
Shahzeb is a Digital Marketer with a Software Engineering background, works as a Community Manager — PHP Community at Cloudways. He is growth ambitious and aims to learn & share information about PHP & Laravel Development through practice and experimentation. He loves to travel and explore new ideas whenever he finds time. Get in touch with him at [email protected]