skip to content

Why can every RIGHT OUTER JOIN be rewritten as a LEFT OUTER JOIN?

level: middleimportance: should knowfreq 52%

answer

  1. both keywords preserve one side
  2. only the written position differs
  3. swap the tables, flip the keyword
  4. the ON predicate is untouched

basics

~20 s

RIGHT OUTER JOIN preserves the table written after the keyword, and LEFT preserves the one written before it. Swapping the two table references and changing RIGHT to LEFT therefore yields the same rows; only the default column order changes.

solid answer

~60 s

The two operators are the same thing pointed in opposite directions. `a RIGHT JOIN b ON p` preserves `b`; `b LEFT JOIN a ON p` preserves `b` as well, with the identical `ON` predicate, so both return the same set of rows. The only difference is textual: the `FROM` clause lists the tables in the other order, so `SELECT *` emits the columns in a different order and any positional reference shifts. Teams standardise on `LEFT` for readability. In a chain such as `FROM a JOIN b … JOIN c …`, a reader scans top-down carrying a growing intermediate result; `LEFT` keeps that mental model, because the accumulated result so far is always the preserved side. A `RIGHT` in the middle of a long chain inverts that silently and is a frequent source of misread queries. The rewrite is not always a local edit: with three or more tables you may have to reorder the whole `FROM` chain, or parenthesise a join, to put the table you want preserved first.

code

sql · 8 lines
sql
-- these two return the same rows
SELECT c.name, o.id AS order_id
FROM orders o
RIGHT OUTER JOIN customers c ON o.customer_id = c.id;

SELECT c.name, o.id AS order_id
FROM customers c
LEFT OUTER JOIN orders o ON o.customer_id = c.id;

go deeper

for a junior

Know that LEFT preserves the table before the keyword and RIGHT the one after it, and that most codebases you join will use LEFT everywhere by convention.

for a middle

Be able to perform the swap on the spot and to state precisely what changes — the FROM order and therefore SELECT * column order — and what does not, which is the row set.

for a senior

Argue the readability case: in a long chain the preserved side should always be the accumulated result, and a single RIGHT inverts that invisibly. Note that flipping a three-table chain is a restructuring, not a keyword edit.

for a principal

Set the convention and back it with review guidance: one join direction, driving table first, joins written in the order a reader accumulates them. Consistency here removes an entire category of silently wrong reporting queries.

## The two operators are mirror images An outer join preserves one side. `LEFT OUTER JOIN` preserves the table written before the keyword; `RIGHT OUTER JOIN` preserves the table written after it. Nothing else distinguishes them — the `ON` predicate, the NULL-extension rule and the treatment of multiple matches are identical. So for two tables, these are equivalent: ```sql FROM orders o RIGHT OUTER JOIN customers c ON o.customer_id = c.id FROM customers c LEFT OUTER JOIN orders o ON o.customer_id = c.id ``` Both preserve `customers`: every customer appears, and customers with no order come back with the `orders` columns NULL-extended. The rewrite recipe is mechanical — swap the two table references, flip the keyword, leave the `ON` predicate exactly as it was. The predicate needs no change because `=` and the other comparison operators do not care which side of the join a column came from. ## What actually changes One thing does differ: the order in which the tables appear in the `FROM` clause. That affects the column order of `SELECT *`, and therefore anything positional built on top of it — an `INSERT … SELECT *`, a client reading columns by index, or `ORDER BY 3`. It is a good argument for naming columns explicitly rather than a reason to avoid the rewrite. ## Why teams write only LEFT A multi-table `FROM` clause reads as a pipeline: start with the first table, join the second onto it, join the third onto that result, and so on. Each line adds columns to a growing intermediate result. With `LEFT JOIN` throughout, the preserved side is always "everything accumulated so far", which matches how a reader is already thinking. A single `RIGHT JOIN` three lines down reverses that: the preserved side becomes the newly introduced table, and every earlier row is now the discardable one. Readers miss it, reviewers miss it, and the query silently loses rows it appeared to guarantee. The convention that follows is: choose the driving table — the one whose rows must all appear — write it first, and use `LEFT JOIN` for everything after it. ## The rewrite is not always local With exactly two tables, flipping is a two-token edit. With three or more it may not be, because the join chain is evaluated left to right and the table you want preserved has to end up in the right structural position. Consider: ```sql FROM a JOIN b ON b.a_id = a.id RIGHT JOIN c ON c.b_id = b.id ``` Here `c` is preserved against the result of `a JOIN b`. To express that with `LEFT`, `c` must come first and the `a`–`b` inner join must stay a unit: ```sql FROM c LEFT JOIN ( SELECT b.id AS b_id, b.a_id, a.name FROM a JOIN b ON b.a_id = a.id ) t ON t.b_id = c.b_id ``` Standard SQL also allows a parenthesised join expression directly in the `FROM` clause for the same purpose. Either way, the point is that reordering a chain is a real restructuring, not a keyword swap, because outer joins do not commute or associate freely the way inner joins do. ## When you might still meet RIGHT Generated SQL, tools that append joins to an existing query, and hand-edits made under pressure all produce `RIGHT JOIN`. It is legal and correct; the objection is stylistic, not semantic. If you inherit one, the useful first step in review is to convert it, because doing so forces you to state which table you actually intend to preserve — and that is exactly the question a mixed-direction chain makes hard to answer. ## The interview answer Name the preserved side for each keyword, give the two-table swap recipe, say that only column order changes, then add the nuance that separates a rote answer from an understood one: with more than two tables the swap may require reordering the whole chain or wrapping part of it, because outer joins are order-sensitive.

  • Is a RIGHT JOIN b truly identical to b LEFT JOIN a, or are there differences?
    The row set is identical and the `ON` predicate is unchanged. What differs is the order of tables in the `FROM` clause, so `SELECT *` returns the columns in a different order and any positional reference — an ordinal in `ORDER BY`, a client reading by index, an `INSERT … SELECT *` — shifts with it. Naming columns explicitly makes the rewrite fully transparent.
  • Why can the rewrite require more than swapping two names when three tables are involved?
    A join chain is evaluated left to right, so each join's left input is the accumulated result so far. Preserving a table that appears late in the chain means moving it to the front and keeping the remaining joins together, typically as a parenthesised join or a derived table. Outer joins are not freely reorderable, so the restructuring must preserve the original grouping.
  • Can mixing LEFT and RIGHT in one query ever be the clearest way to write it?
    Rarely. Any mixed chain has an equivalent all-LEFT form, possibly with a derived table, and the all-LEFT form states the driving table explicitly in the first line of the FROM clause. The usual reason a RIGHT appears is incremental editing rather than intent, which is why converting it during review is a cheap way to surface what the author actually meant.

saying these in an interview costs you the question

  • Thinks RIGHT JOIN preserves the first table listed
  • Believes the ON predicate must be rewritten when flipping
  • Claims the two forms return different rows, not just different column order
  • Assumes any three-table chain can be flipped by swapping keywords
  • Says RIGHT JOIN is unsupported rather than merely unfashionable

context