RIGHT JOIN
Returns all rows from the right table, plus matching rows from the left.
SELECT columns FROM left_table RIGHT JOIN right_table ON left_table.id = right_table.fk_id;This static page keeps the syntax and examples indexed for search, while the coding app handles interactive exploration and saved references.
What it does
Overview
Returns all rows from the right table, plus matching rows from the left.
The RIGHT JOIN (or RIGHT OUTER JOIN) keyword returns all records from the right table (table2), and the matching records from the left table (table1). If there is no match for a specific row in the right table, the resulting columns from the left table will contain NULL values. While functionally equivalent to a LEFT JOIN with the table order reversed, RIGHT JOIN is used less frequently in professional environments because most developers find a 'starting table' (left-to-right) mental model more intuitive for query logic. From a performance perspective, modern query optimizers (such as those in PostgreSQL, MySQL, or SQL Server) typically treat RIGHT JOIN and LEFT JOIN identically by transforming the execution plan into the most efficient join type (e.g., Hash Join or Merge Join). However, an important edge case occurs when using the WHERE clause: if you filter on a column from the left table that is not part of the join condition, you may unintentionally filter out the NULLs produced by the RIGHT JOIN, effectively converting the operation into an INNER JOIN. For best performance, ensure that the columns used in the ON clause are indexed.
Quick reference
Syntax
SELECT columns FROM left_table RIGHT JOIN right_table ON left_table.id = right_table.fk_id;
Inputs
Parameters
See it in practice
Examples
Basic RIGHT JOIN for Department Coverage
SELECT employees.name, departments.dept_name
FROM employees
RIGHT JOIN departments
ON employees.dept_id = departments.id;| name | dept_name | |---|---| | Alice | Sales | | Bob | Engineering | | NULL | Marketing |
Returns all departments, including 'Marketing' which currently has no assigned employees (resulting in a NULL name).
Identifying 'Orphan' Records in the Right Table
SELECT d.dept_name
FROM employees e
RIGHT JOIN departments d
ON e.dept_id = d.id
WHERE e.id IS NULL;| dept_name | |---| | Marketing |
Uses a RIGHT JOIN combined with a NULL check to find departments that do not have any associated employees.
Right Join Across Regional Data
SELECT r.region_name, d.dept_name
FROM departments d
RIGHT JOIN regions r
ON d.region_id = r.id
ORDER BY r.region_name ASC;| region_name | dept_name | |---|---| | EMEA | Sales | | LATAM | NULL | | NA | Engineering |
Ensures every region is listed in the final report, even if no departments are currently operational in that specific region.
Debug faster
Common Errors
LogicError
Cause: Using a WHERE clause on the left table's columns that does not account for NULLs, which forces the query to act like an INNER JOIN.
Fix: Move the condition to the ON clause or explicitly check for NULL in the WHERE clause.
-- Bad: Removes the NULL rows generated by the RIGHT JOIN
SELECT * FROM employees e RIGHT JOIN departments d ON e.dept_id = d.id WHERE e.status = 'Active';AmbiguousColumnError
Cause: Selecting columns that exist in both the left and right tables without using table aliases.
Fix: Always prefix column names with table names or aliases (e.g., table_a.id).
-- Bad: If both tables have an 'id' column
SELECT id FROM table_a RIGHT JOIN table_b ON table_a.fk = table_b.id;Runtime support
Compatibility
SQLite does not support RIGHT JOIN (rewrite as LEFT JOIN)
Source: MDN Web Docs
Common questions
Frequently Asked Questions
Returns all rows from the right table, plus matching rows from the left.
able: Left side table (matched rows included). able: Right side table (all rows preserved). ON condition: Join condition defining the relationship.
LogicError: Move the condition to the ON clause or explicitly check for NULL in the WHERE clause. AmbiguousColumnError: Always prefix column names with table names or aliases (e.g., .id).