SQL RIGHT JOIN: Syntax, Examples & Practice
SQL RIGHT JOIN returns every row from the right table, plus the matching rows from the left table. Where a right row has no match, it still appears, with NULL in the left table's columns. It is a LEFT JOIN with the two tables swapped, and RIGHT OUTER JOIN is the same thing.
What Is a RIGHT JOIN in SQL?
The Playground database has an orders table and a users table of customers. Some customers have never ordered. This query starts from orders but still returns every customer, because users is on the right-hand side of a RIGHT JOIN:
SELECT o.id AS order_id, o.total,
u.id AS user_id, u.first_name
FROM orders o
RIGHT JOIN users u
ON o.user_id = u.id
WHERE u.id <= 5
ORDER BY u.id, o.id;
▶ Run this query in the SQL Playground
| order_id | total | user_id | first_name |
|---|---|---|---|
| 109 | 4064.75 | 1 | Jennifer |
| 13 | 1618.29 | 2 | Donna |
| NULL | NULL | 3 | Kenneth |
| 11 | 1518.36 | 4 | Michael |
| 87 | 2501.23 | 4 | Michael |
| 181 | 843.7 | 4 | Michael |
| 127 | 4924.23 | 5 | Robert |
Kenneth has no orders, but he is still in the result: the two columns that come from orders, the left table, are NULL. Michael has three orders and appears three times. Five customers produce 7 rows.
"Right" only means "written after the words RIGHT JOIN". The right table is the one whose rows are all kept; the left table supplies matches where they exist. An INNER JOIN would have dropped Kenneth.
RIGHT JOIN Syntax
SELECT columns
FROM left_table
RIGHT JOIN right_table
ON left_table.key = right_table.key;
| Part | What it does |
|---|---|
FROM left_table | Supplies matching rows only. Its columns are NULL for unmatched right rows. |
RIGHT JOIN right_table | The table whose rows are all kept. |
ON … | The matching rule, usually a foreign key compared with the primary key it points to. |
RIGHT OUTER JOIN | The full name of the same join. OUTER is optional. |
Database support
| Database | RIGHT JOIN |
|---|---|
| MySQL, MariaDB | Supported |
| PostgreSQL | Supported |
| SQL Server | Supported |
| Oracle | Supported |
| SQLite | Supported from version 3.39 (2022). In older versions, swap the tables and use LEFT JOIN. |
How RIGHT JOIN Works
For each row of the right table, the database looks for rows in the left table that satisfy ON:
| Right row has… | Rows in the result | Left-table columns |
|---|---|---|
| One match | 1 | Filled from the matching row |
| Several matches | One per match | Filled from each matching row |
| No match | 1 | All NULL |
Left rows that match nothing are dropped. The result therefore never has fewer rows than the right table:
SELECT COUNT(*) AS result_rows,
COUNT(DISTINCT u.id) AS customers,
COUNT(o.id) AS matched_orders,
COUNT(*) - COUNT(o.id) AS customers_without_orders
FROM orders o
RIGHT JOIN users u
ON o.user_id = u.id;
▶ Run this query in the SQL Playground
| result_rows | customers | matched_orders | customers_without_orders |
|---|---|---|---|
| 236 | 150 | 200 | 36 |
All 150 customers are present: 200 rows for orders that matched, plus 36 NULL rows for customers who never ordered, 236 in total.
RIGHT JOIN vs LEFT JOIN
The same join, read from the other side.
A RIGHT JOIN B and B LEFT JOIN A are the same query. Both keep every row of B. Swap the two tables, change the keyword, and nothing else:
-- keeps every customer
SELECT u.first_name, o.id
FROM orders o
RIGHT JOIN users u
ON o.user_id = u.id;
-- identical result
SELECT u.first_name, o.id
FROM users u
LEFT JOIN orders o
ON o.user_id = u.id;
SELECT 'orders RIGHT JOIN users' AS query,
COUNT(*) AS rows_returned, COUNT(o.id) AS matched
FROM orders o
RIGHT JOIN users u ON o.user_id = u.id
UNION ALL
SELECT 'users LEFT JOIN orders', COUNT(*), COUNT(o.id)
FROM users u
LEFT JOIN orders o ON o.user_id = u.id;
▶ Run this query in the SQL Playground
| query | rows_returned | matched |
|---|---|---|
| orders RIGHT JOIN users | 236 | 200 |
| users LEFT JOIN orders | 236 | 200 |
| LEFT JOIN | RIGHT JOIN | |
|---|---|---|
| Keeps every row of | The first (left) table | The second (right) table |
| NULLs appear in | Right-table columns | Left-table columns |
| Unmatched rows dropped from | The right table | The left table |
| Rewrite as the other | Swap the tables | Swap the tables |
| How often it is written | Very often | Rarely |
Which one should you use?
Most teams write LEFT JOIN everywhere. A reader then knows the first table in FROM is the complete one, and every later join only adds optional detail. A query that mixes LEFT and RIGHT joins is much harder to follow. RIGHT JOIN is still worth knowing for three reasons:
| Where you meet RIGHT JOIN | Why |
|---|---|
| Existing and generated SQL | Report builders, ORMs and older code produce it, and you have to read it correctly. |
| Adding a "must keep" table to a finished query | Appending RIGHT JOIN calendar can be a smaller change than rewriting the FROM clause. |
| Interviews | Rewriting a RIGHT JOIN as a LEFT JOIN is a quick test of whether you understand join direction. |
RIGHT JOIN vs INNER JOIN and FULL OUTER JOIN
To see all four joins give different answers, both tables need rows the other lacks. Take the customers who ordered in 2023 as the left side and those who ordered in 2024 as the right side:
WITH y2023 AS (
SELECT DISTINCT user_id FROM orders
WHERE order_date >= '2023-01-01' AND order_date < '2024-01-01'
), y2024 AS (
SELECT DISTINCT user_id FROM orders
WHERE order_date >= '2024-01-01' AND order_date < '2025-01-01'
)
SELECT 'INNER JOIN' AS join_type, COUNT(*) AS customers
FROM y2023 a INNER JOIN y2024 b ON a.user_id = b.user_id
UNION ALL
SELECT 'LEFT JOIN', COUNT(*)
FROM y2023 a LEFT JOIN y2024 b ON a.user_id = b.user_id
UNION ALL
SELECT 'RIGHT JOIN', COUNT(*)
FROM y2023 a RIGHT JOIN y2024 b ON a.user_id = b.user_id
UNION ALL
SELECT 'FULL OUTER JOIN', COUNT(*)
FROM y2023 a FULL OUTER JOIN y2024 b ON a.user_id = b.user_id;
▶ Run this query in the SQL Playground
| join_type | customers |
|---|---|
| INNER JOIN | 19 |
| LEFT JOIN | 51 |
| RIGHT JOIN | 56 |
| FULL OUTER JOIN | 88 |
| Join | Rows | Meaning |
|---|---|---|
| INNER JOIN | 19 | Ordered in both years |
| LEFT JOIN | 51 | Everyone who ordered in 2023 |
| RIGHT JOIN | 56 | Everyone who ordered in 2024 |
| FULL OUTER JOIN | 88 | Everyone who ordered in either year |
The RIGHT JOIN rows show who is new in 2024: the left column is NULL for customers with no 2023 order.
WITH y2023 AS (
SELECT DISTINCT user_id FROM orders
WHERE order_date >= '2023-01-01' AND order_date < '2024-01-01'
), y2024 AS (
SELECT DISTINCT user_id FROM orders
WHERE order_date >= '2024-01-01' AND order_date < '2025-01-01'
)
SELECT a.user_id AS ordered_2023,
b.user_id AS ordered_2024
FROM y2023 a
RIGHT JOIN y2024 b
ON a.user_id = b.user_id
ORDER BY b.user_id
LIMIT 6;
▶ Run this query in the SQL Playground
| ordered_2023 | ordered_2024 |
|---|---|
| NULL | 4 |
| NULL | 5 |
| 8 | 8 |
| 10 | 10 |
| NULL | 11 |
| 16 | 16 |
A FULL OUTER JOIN keeps the unmatched rows of both tables; RIGHT JOIN keeps them for the right table only. The WITH blocks at the top are CTEs, named subqueries that keep the joins readable.
Finding Unmatched Rows With RIGHT JOIN … IS NULL
After a RIGHT JOIN, a right row with no match has NULL in every left-table column. Filter on that with IS NULL to list the right rows that have nothing attached. Which products have never been reviewed?
SELECT p.id, p.name, p.category
FROM reviews r
RIGHT JOIN products p
ON r.product_id = p.id
WHERE r.id IS NULL
ORDER BY p.id;
▶ Run this query in the SQL Playground
| id | name | category |
|---|---|---|
| 7 | Giant Stuffed Teddy Bear | Toys |
| 9 | Merino Wool Sweater | Clothing |
| 13 | Retinol Eye Cream 30ml | Health & Beauty |
| 14 | Play Kitchen Deluxe | Toys |
| 19 | Resistance Bands Set | Sports & Outdoors |
| 22 | Back Seat Organizer | Automotive |
27 products have no review. Test the left table's primary key (r.id): it can only be NULL when no row matched.
Checking for orphaned rows
The same pattern is a data-quality check. An order should always belong to a customer; a RIGHT JOIN from users to orders keeps every order and exposes any that point at a customer who does not exist:
SELECT COUNT(*) AS orders_without_a_customer
FROM users u
RIGHT JOIN orders o
ON u.id = o.user_id
WHERE u.id IS NULL;
▶ Run this query in the SQL Playground
| orders_without_a_customer |
|---|
| 0 |
The Playground data is clean, so the count is 0. On imported or migrated data this query is how broken references are usually found.
RIGHT JOIN With a WHERE Clause
A condition on the left table belongs in ON, or the join stops keeping every right row.
You want every order with its number of successful payments. The condition p.status = 'success' is about payments, the left table. Compare the two places it can go:
SELECT 'condition in WHERE' AS version, COUNT(DISTINCT o.id) AS orders_returned
FROM payments p
RIGHT JOIN orders o ON p.order_id = o.id
WHERE p.status = 'success'
UNION ALL
SELECT 'condition in ON', COUNT(DISTINCT o.id)
FROM payments p
RIGHT JOIN orders o ON p.order_id = o.id AND p.status = 'success';
▶ Run this query in the SQL Playground
| version | orders_returned |
|---|---|
| condition in WHERE | 99 |
| condition in ON | 200 |
In WHERE, only 99 of 200 orders remain. WHERE runs after the join, and for an order with no payment p.status is NULL, so the row fails the test. In ON, the condition only decides which payments count as a match:
SELECT o.id AS order_id, o.status,
COUNT(p.id) AS successful_payments
FROM payments p
RIGHT JOIN orders o
ON p.order_id = o.id
AND p.status = 'success'
WHERE o.id <= 6
GROUP BY o.id, o.status
ORDER BY o.id;
▶ Run this query in the SQL Playground
| order_id | status | successful_payments |
|---|---|---|
| 1 | cancelled | 0 |
| 2 | delivered | 2 |
| 3 | delivered | 2 |
| 4 | processing | 0 |
| 5 | delivered | 0 |
| 6 | shipped | 0 |
| Condition on… | Put it in | Because |
|---|---|---|
| The left table | ON | It limits what can match and leaves unmatched right rows in place. |
| The right table | WHERE | It removes right rows you do not want at all (as o.id <= 6 does above). |
| "No match exists" | WHERE left.id IS NULL | The one left-table test that belongs in WHERE. |
RIGHT JOIN With GROUP BY and COUNT
A RIGHT JOIN keeps groups that would otherwise have no rows, so zeros show up in a report. How many directors does each department have?
SELECT d.name AS department,
COUNT(e.id) AS directors
FROM employees e
RIGHT JOIN departments d
ON e.department_id = d.id
AND e.title LIKE '%Director%'
GROUP BY d.id, d.name
ORDER BY directors DESC, d.name;
▶ Run this query in the SQL Playground
| department | directors |
|---|---|
| Product | 4 |
| Customer Success | 2 |
| Design | 2 |
| HR | 2 |
| Operations | 2 |
| Engineering | 0 |
| Finance | 0 |
| Legal | 0 |
| Marketing | 0 |
| Sales | 0 |
Five departments have no director and still appear, with 0. Two things make that work: the title condition is in ON, and the count is COUNT(e.id), which ignores NULL. COUNT(*) would report 1 for those departments, because each still has one row. Other aggregates over no rows, such as SUM and AVG, return NULL; wrap them in COALESCE if you want 0.
RIGHT JOIN on Multiple Tables
Joins are applied in the order they are written. Each RIGHT JOIN keeps every row of the table it introduces, so in a chain the last table is the one that is complete:
SELECT u.id AS user_id, u.first_name,
o.id AS order_id, oi.product_id, oi.quantity
FROM order_items oi
RIGHT JOIN orders o
ON oi.order_id = o.id
RIGHT JOIN users u
ON o.user_id = u.id
WHERE u.id <= 3
ORDER BY u.id, o.id, oi.id;
▶ Run this query in the SQL Playground
| user_id | first_name | order_id | product_id | quantity |
|---|---|---|---|---|
| 1 | Jennifer | 109 | 43 | 4 |
| 2 | Donna | 13 | 87 | 4 |
| 2 | Donna | 13 | 30 | 1 |
| 2 | Donna | 13 | 10 | 5 |
| 3 | Kenneth | NULL | NULL | NULL |
Kenneth has no order, so both the order and the item columns are NULL, but he is kept. The same report written with LEFT JOINs starts from the table that must be complete, which is why most people find it easier to read:
SELECT u.id AS user_id, u.first_name,
o.id AS order_id, oi.product_id, oi.quantity
FROM users u
LEFT JOIN orders o
ON o.user_id = u.id
LEFT JOIN order_items oi
ON oi.order_id = o.id
WHERE u.id <= 3
ORDER BY u.id, o.id, oi.id;
Where RIGHT JOIN Is Used
| Question | Left table → right table (kept) |
|---|---|
| Every department with its headcount, empty ones included | employees → departments |
| Products that have never been ordered or reviewed | order_items / reviews → products |
| Orders that point at a missing customer (data audit) | customers → orders |
| Sales rows whose product is not in the catalogue | products → sales |
| Courses with no enrolled students | enrollments → courses |
| Rooms with no booking tonight | bookings → rooms |
| Every day on a chart, including days with no sales | sales → calendar |
| Pricing plans nobody has subscribed to | subscriptions → plans |
Every row of this table could be written as a LEFT JOIN with the tables in the other order. Spreadsheet and BI tools offer the same join as "Right Outer" in their merge dialogs.
Common RIGHT JOIN Mistakes
1. Keeping the wrong table
SELECT u.first_name, o.id
FROM users u
RIGHT JOIN orders o
ON o.user_id = u.id;
SELECT u.first_name, o.id
FROM orders o
RIGHT JOIN users u
ON o.user_id = u.id;
RIGHT JOIN keeps the table written after it. To keep every customer, users must be on the right, or use users LEFT JOIN orders.
2. Filtering the left table in WHERE
SELECT o.id, p.id
FROM payments p
RIGHT JOIN orders o
ON p.order_id = o.id
WHERE p.status = 'success';
SELECT o.id, p.id
FROM payments p
RIGHT JOIN orders o
ON p.order_id = o.id
AND p.status = 'success';
For unmatched right rows the left columns are NULL, so a WHERE test on them fails and the join behaves like an INNER JOIN. See RIGHT JOIN with a WHERE clause.
3. Testing for NULL with =
SELECT p.name
FROM reviews r
RIGHT JOIN products p
ON r.product_id = p.id
WHERE r.id = NULL;
SELECT p.name
FROM reviews r
RIGHT JOIN products p
ON r.product_id = p.id
WHERE r.id IS NULL;
Nothing is equal to NULL, so = NULL is never true. Use IS NULL.
4. COUNT(*) on a RIGHT JOIN
SELECT d.name, COUNT(*)
FROM employees e
RIGHT JOIN departments d
ON e.department_id = d.id
GROUP BY d.name;
SELECT d.name, COUNT(e.id)
FROM employees e
RIGHT JOIN departments d
ON e.department_id = d.id
GROUP BY d.name;
An unmatched right row is still one row. Counting a column from the left table skips its NULL and gives 0.
5. Mixing LEFT and RIGHT joins in one query
SELECT u.id, o.id, p.id
FROM orders o
RIGHT JOIN users u ON o.user_id = u.id
LEFT JOIN payments p ON p.order_id = o.id;
SELECT u.id, o.id, p.id
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
LEFT JOIN payments p ON p.order_id = o.id;
Both queries return the same rows, but the second reads top to bottom: start with every customer, then add what exists.
RIGHT JOIN Performance
A RIGHT JOIN costs the same as the equivalent LEFT JOIN. Database optimisers treat the two as the same operation, so choosing between them is a readability decision, not a speed one. What matters is the usual join advice:
| Tip | Why it helps |
|---|---|
| Index the join column of the left table | For each right row the database looks up matches there. Foreign keys such as orders.user_id usually need an index. |
| Filter the right table in WHERE | Fewer rows to keep means fewer lookups, and it does not change the join's meaning. |
| Select only the columns you need | SELECT * across several joins returns far more data than a report uses. |
RIGHT JOIN Cheat Sheet
| Goal | Pattern |
|---|---|
| All right rows, with matches if any | FROM a RIGHT JOIN b ON a.b_id = b.id |
| Right rows with no match | … RIGHT JOIN b ON … WHERE a.id IS NULL |
| Count matches, zeros included | COUNT(a.id) with GROUP BY b.id |
| Filter which left rows may match | Add the condition to ON, not WHERE |
| Rewrite as LEFT JOIN | FROM b LEFT JOIN a ON a.b_id = b.id |
| Keep unmatched rows from both tables | FULL OUTER JOIN |
Practice RIGHT JOIN Queries
7 exercises on the real Playground tables.
Write each query yourself first. Every solution has been run against the Playground database.
-
1Easy Using RIGHT JOIN, list customers 10 to 20 with the id and status of each of their orders. Customers with no orders must appear. Table:
orders, usersShow solution
SELECT u.id AS user_id, u.first_name, o.id AS order_id, o.status FROM orders o RIGHT JOIN users u ON o.user_id = u.id WHERE u.id BETWEEN 10 AND 20 ORDER BY u.id, o.id;▶ Run this query in the SQL Playground
usersis on the right, so all eleven customers are kept; the filter on the right table is safe in WHERE. The result has 14 rows. -
2Easy Using RIGHT JOIN, find any product that has never been ordered. Table:
order_items, productsShow solution
SELECT p.id, p.name, p.category FROM order_items oi RIGHT JOIN products p ON oi.product_id = p.id WHERE oi.id IS NULL;▶ Run this query in the SQL Playground
RIGHT JOIN keeps every product and
oi.id IS NULLleaves only those with no order item: 1 product. -
3Medium Rewrite this as a RIGHT JOIN that returns the same rows: users LEFT JOIN orders, showing each customer id and their number of orders, for customers 1 to 8. Table:
users, ordersShow solution
SELECT u.id, COUNT(o.id) AS orders FROM orders o RIGHT JOIN users u ON o.user_id = u.id WHERE u.id <= 8 GROUP BY u.id ORDER BY u.id;▶ Run this query in the SQL Playground
Swap the two tables and change LEFT to RIGHT. The ON condition, the columns and the grouping stay the same.
-
4Medium Using RIGHT JOIN, count the orders that have no payment at all. Table:
payments, ordersShow solution
SELECT COUNT(*) AS unpaid_orders FROM payments p RIGHT JOIN orders o ON p.order_id = o.id WHERE p.id IS NULL;▶ Run this query in the SQL Playground
After the IS NULL filter every remaining row is one order with no payment, so
COUNT(*)is right here. -
5Medium For each product category, count the products that have no reviews. Use RIGHT JOIN. Table:
reviews, productsShow solution
SELECT p.category, COUNT(*) AS products_without_reviews FROM reviews r RIGHT JOIN products p ON r.product_id = p.id WHERE r.id IS NULL GROUP BY p.category ORDER BY products_without_reviews DESC, p.category;▶ Run this query in the SQL Playground
The anti-join leaves one row per unreviewed product; grouping by category counts them. 10 categories have at least one.
-
6Challenging For every department, count the employees hired in 2024. Departments with none must show 0. Use RIGHT JOIN. Table:
employees, departmentsShow solution
SELECT d.name AS department, COUNT(e.id) AS hired_2024 FROM employees e RIGHT JOIN departments d ON e.department_id = d.id AND e.hire_date >= '2024-01-01' AND e.hire_date < '2025-01-01' GROUP BY d.id, d.name ORDER BY hired_2024 DESC, d.name;▶ Run this query in the SQL Playground
The date range is a condition on the left table, so it goes in ON. In WHERE it would remove departments with no 2024 hire.
-
7Challenging Find the customers who ordered in 2024 but not in 2023. Join the 2023 buyers to the 2024 buyers with a RIGHT JOIN. Table:
ordersShow solution
WITH y2023 AS ( SELECT DISTINCT user_id FROM orders WHERE order_date >= '2023-01-01' AND order_date < '2024-01-01' ), y2024 AS ( SELECT DISTINCT user_id FROM orders WHERE order_date >= '2024-01-01' AND order_date < '2025-01-01' ) SELECT b.user_id FROM y2023 a RIGHT JOIN y2024 b ON a.user_id = b.user_id WHERE a.user_id IS NULL ORDER BY b.user_id;▶ Run this query in the SQL Playground
The RIGHT JOIN keeps every 2024 buyer;
a.user_id IS NULLkeeps those with no 2023 match. 37 customers are new in 2024.
📝 Quiz — RIGHT JOIN
Test your understanding · 0/10 answered
What does a RIGHT JOIN return?
Every right-table row is returned. Matching left-table rows are attached, and unmatched right rows get NULL in the left-table columns.
Which query returns the same rows as A RIGHT JOIN B?
RIGHT JOIN keeps every row of B. Making B the left table of a LEFT JOIN does exactly the same.
In orders RIGHT JOIN users, where do the NULLs appear for a customer with no orders?
The customer (right table) is kept. The columns from orders, the left table, are NULL.
Is RIGHT OUTER JOIN different from RIGHT JOIN?
RIGHT JOIN is short for RIGHT OUTER JOIN. The OUTER keyword is optional.
Which join keeps unmatched rows from both tables?
FULL OUTER JOIN keeps unmatched rows on both sides. RIGHT JOIN keeps them for the right table only.
reviews r RIGHT JOIN products p … WHERE r.id IS NULL returns:
Every product is kept; r.id is NULL only where no review matched, so the filter leaves the unreviewed products.
payments p RIGHT JOIN orders o … WHERE p.status = 'success'. What happens to orders with no payment?
p.status is NULL for those orders, so the WHERE test is not true. Move the condition into ON to keep them.
In A RIGHT JOIN B RIGHT JOIN C, which table is guaranteed to be complete?
Joins are applied in order and each RIGHT JOIN keeps the table it introduces, so the last one, C, has all its rows.
Is a RIGHT JOIN slower than the equivalent LEFT JOIN?
They are the same operation written from opposite sides. Performance is identical.
Why do most teams prefer LEFT JOIN to RIGHT JOIN?
It is a readability convention: start from the table that must be complete, then add optional data with LEFT JOINs.
RIGHT JOIN Interview Questions
Q1. What is a RIGHT JOIN?
A join that returns every row from the right (second) table and the matching rows from the left table. Right rows with no match are still returned, with NULL in the left table's columns. RIGHT OUTER JOIN is the same join.
Q2. What is the difference between LEFT JOIN and RIGHT JOIN?
Only the side that is kept. LEFT JOIN keeps every row of the first table, RIGHT JOIN every row of the second. A RIGHT JOIN B is equivalent to B LEFT JOIN A.
Q3. How do you rewrite a RIGHT JOIN as a LEFT JOIN?
Swap the two tables and change the keyword. The ON condition and the rest of the query stay as they are.
Q4. What is the difference between RIGHT JOIN and INNER JOIN?
INNER JOIN returns only matching rows. RIGHT JOIN also returns the right-table rows that have no match, with NULLs on the left.
Q5. What is the difference between RIGHT JOIN and FULL OUTER JOIN?
RIGHT JOIN keeps unmatched rows of the right table only. FULL OUTER JOIN keeps unmatched rows of both tables, so it returns everything a LEFT JOIN and a RIGHT JOIN would return between them.
Q6. How do you find rows in the right table that have no match?
RIGHT JOIN and filter with WHERE left_table.id IS NULL, testing a column that cannot be NULL in a real row. For example, departments with no employees: FROM employees e RIGHT JOIN departments d ON e.department_id = d.id WHERE e.id IS NULL.
Q7. Why is RIGHT JOIN rarely used?
Because it adds nothing a LEFT JOIN cannot do, and queries are easier to read when the complete table always comes first. Many style guides ask for LEFT JOIN only.
Q8. Where does a filter on the left table go in a RIGHT JOIN?
In the ON clause. In WHERE it would fail for the unmatched right rows, whose left columns are NULL, and remove them.
Q9. Can a RIGHT JOIN return more rows than the right table has?
Yes. A right row with several matching left rows is returned once per match. It never returns fewer rows than the right table unless WHERE removes them.
Q10. How do you join three tables with RIGHT JOIN?
Chain the joins: A RIGHT JOIN B ON … RIGHT JOIN C ON …. They are evaluated left to right, so the last table is the one guaranteed to be complete.
Q11. Do all databases support RIGHT JOIN?
MySQL, PostgreSQL, SQL Server and Oracle do. SQLite added RIGHT and FULL OUTER JOIN in version 3.39; before that the workaround was a LEFT JOIN with the tables swapped.
Q12. How would you use RIGHT JOIN to audit data?
Join the parent table to the child with the child on the right and keep rows where the parent key IS NULL. Those are child rows, such as orders, whose parent, such as a customer, does not exist.
Frequently Asked Questions
What is RIGHT JOIN in SQL?
RIGHT JOIN returns every row from the right table and the matching rows from the left table. When a right row has no match, it is still returned, with NULL in the left table's columns.
What is the difference between LEFT JOIN and RIGHT JOIN?
LEFT JOIN keeps every row of the first table; RIGHT JOIN keeps every row of the second. They are mirror images, and A RIGHT JOIN B returns the same rows as B LEFT JOIN A.
Is RIGHT JOIN the same as RIGHT OUTER JOIN?
Yes. RIGHT JOIN is the short form of RIGHT OUTER JOIN. The OUTER keyword is optional and does not change the result.
When should I use RIGHT JOIN instead of LEFT JOIN?
Almost never by necessity, since any RIGHT JOIN can be written as a LEFT JOIN. It is convenient when you add a table that must be complete to the end of an existing query, and you need to understand it to read other people's SQL.
Why does RIGHT JOIN return NULL values?
A right-table row with no matching left-table row has no data to show for the left columns, so they are NULL. That NULL is how you detect rows with no match.
How do I find unmatched rows with RIGHT JOIN?
Add WHERE left_table.id IS NULL after the join. Only the right-table rows that found no match remain.
Does SQLite support RIGHT JOIN?
Yes, from SQLite 3.39, released in 2022. Earlier versions support only LEFT JOIN, so the tables have to be swapped.
Is RIGHT JOIN slower than LEFT JOIN?
No. They are the same operation written from opposite sides, and the database plans them the same way.