Interview questions

Inner Outer Join SQL Interview: Predict the Output Fast

August 5, 2025Updated May 9, 202617 min read
Why Understanding Inner And Outer Join In Sql Is Essential For Acing Technical Interviews

Master inner outer join SQL interview questions by predicting query output from tiny tables, including INNER, LEFT, RIGHT, and FULL OUTER JOIN cases.

You know what an inner join does. You could write the definition in your sleep. But when an interviewer drops two four-row tables on a shared screen and asks "what does this query return?" — that's where the definition stops helping. The real skill tested in an inner outer join SQL interview isn't recall. It's whether you can trace each row through the join logic and land on the exact output before the interviewer finishes the question.

This guide is about that skill: predicting rows, not reciting definitions. The sections below build a row-retention model you can apply to any join question, including the traps most candidates don't see coming until they've already given the wrong answer.

Say the short version first: inner join keeps matches, outer join keeps the leftovers too

What an interviewer actually wants in 10 seconds

The one-sentence version that works under pressure: an inner join returns only the rows where the join condition is satisfied on both sides; an outer join returns those rows plus the unmatched ones from one or both sides, filling the gaps with NULL. That's the whole model. Everything else is a variation on which side's leftovers you're keeping.

When you say this out loud in an interview, you're signaling that you understand row retention — not just join syntax. That's the distinction that separates a candidate who has used joins from one who has only read about them.

Why people overcomplicate the first answer

The memorized version sounds like this: "An inner join returns the Cartesian product filtered by a condition, while an outer join preserves unmatched rows from the specified table." Technically accurate. Practically useless when the interviewer asks what the specific query returns from the specific tables on the screen.

The definition breaks down because it doesn't give you a working procedure. You can't apply "Cartesian product filtered by condition" row by row in your head in 30 seconds. The inner vs outer join distinction only becomes useful when you translate it into a concrete question: for each row on the left, did it find a match on the right? If yes, it's in every join type. If no, it survives only in an outer join — and only on the side that outer join is protecting.

What this looks like in practice

Take two tables: `orders` (id 1, 2, 3) and `customers` (id 2, 3, 4). The join condition is `orders.customer_id = customers.id`.

Row 1 in orders has no matching customer. Rows 2 and 3 match. Customer 4 has no matching order.

`INNER JOIN` returns two rows: the matches for id 2 and id 3. `LEFT OUTER JOIN` returns three rows: the two matches plus order id 1 with NULLs for the customer columns.

That one unmatched row is the entire difference. If you can see that in a tiny table, you can answer the question. According to the PostgreSQL documentation on joins, the outer join NULL-filling behavior is defined precisely this way: unmatched rows from the preserved side are included with NULL substituted for the other table's columns.

In real interview loops, candidates who define joins correctly still miss the output rows because they never practiced tracing the unmatched row. They know the vocabulary. They haven't built the model.

Build the row-retention model before you touch SQL

The table you start with is not always the table you end with

Join questions are really questions about survival. Each source row either finds a match and gets included, or it doesn't — and what happens next depends entirely on the join type. Inner join: unmatched rows are dropped. Outer join: unmatched rows are preserved with NULLs. The row count in your output is determined by those two rules, not by the size of either input table.

This reframe matters because it lets you predict join output without writing a single line of SQL. Before you type anything, ask: how many rows match? How many don't? Which side is protected? Answer those three questions and you already know the shape of the result.

What this looks like in practice

Here's the dataset used throughout this guide. Keep it handy — it's small enough to hold in your head and covers every case.

employees table:

  • id 1, name Alice, dept_id 10
  • id 2, name Bob, dept_id 20
  • id 3, name Carol, dept_id 30

departments table:

  • dept_id 10, name Engineering
  • dept_id 20, name Marketing
  • dept_id 40, name Finance

Matches: Alice → Engineering, Bob → Marketing. Carol (dept_id 30) has no matching department. Finance (dept_id 40) has no matching employee.

Walk through it row by row before running any query. Alice: match exists, survives every join type. Bob: match exists, survives every join type. Carol: no match on the right side, survives only if the left side is protected. Finance: no match on the left side, survives only if the right side is protected.

That's the model. Two matches, one unmatched left row, one unmatched right row. Every join type produces a different subset of those four cases, and you can predict which subset before you touch the keyboard. The MySQL reference manual on JOIN syntax documents this NULL-filling behavior explicitly and is worth bookmarking as a source of truth for output rules.

Predict the INNER JOIN output before you see the answer

Start with the overlap, not the full table

INNER JOIN output is the intersection. Only rows with a match on both sides make it through. The common mistake is mentally including a row because it exists in one of the tables — which is exactly the wrong instinct. Existence in a table is irrelevant. Existence in the join result depends entirely on whether the condition is satisfied.

From the dataset above: Alice and Bob match. Carol does not. Finance does not. INNER JOIN returns exactly two rows: Alice/Engineering and Bob/Marketing.

What this looks like in practice

Try to predict before reading the answer. The query:

Expected output:

  • Alice, Engineering
  • Bob, Marketing

Carol is gone. Finance is gone. Two rows from three employees and three departments. If you predicted three or four rows, you included an unmatched row — which means you were thinking about table size instead of match logic.

The follow-up question interviewers love

"What if one employee maps to multiple departments?" This is the one-to-many trap. If Bob had two matching rows in `departments`, the INNER JOIN would return two rows for Bob — one for each match. The row multiplies. This surprises candidates who assume one input row always produces one output row.

The rule: each match creates a row. One-to-many means many rows in the output. This is also why a missing `ON` condition or a cartesian join produces a row count equal to the product of both table sizes — every row matches every other row. According to the SQL standard documentation referenced by major vendors, this multiplicative behavior is the defined result of satisfying the join predicate multiple times for a single row.

In a live whiteboard session, candidates who account for row multiplication in their answer immediately signal they've debugged real queries — not just read about joins.

Left, right, and full outer joins are just different rules for keeping the leftovers

LEFT JOIN: keep everything from the left, even when it has nowhere to go

The left right full outer join family all work the same way: they extend the inner join result by refusing to drop unmatched rows from one or both sides. LEFT JOIN is the most common version. The rule: every row from the left table appears in the output. If it matched, the right-side columns are populated. If it didn't match, the right-side columns are NULL.

From the dataset: Alice matches, Bob matches, Carol does not. LEFT JOIN output is three rows — Alice/Engineering, Bob/Marketing, Carol/NULL. Finance disappears entirely because the right side is not protected.

RIGHT JOIN and FULL OUTER JOIN: the same idea, just wider

RIGHT JOIN mirrors LEFT JOIN exactly. Every row from the right table appears. Unmatched left rows are dropped. From the dataset: Alice/Engineering, Bob/Marketing, NULL/Finance. Carol disappears.

FULL OUTER JOIN refuses to drop anything. Every unmatched row from either side gets preserved with NULLs on the missing side. Output: Alice/Engineering, Bob/Marketing, Carol/NULL, NULL/Finance. Four rows from three employees and three departments.

What this looks like in practice

Same dataset, three different queries, three different row counts:

LEFT JOIN output:

  • Alice, Engineering
  • Bob, Marketing
  • Carol, NULL

RIGHT JOIN output:

  • Alice, Engineering
  • Bob, Marketing
  • NULL, Finance

FULL OUTER JOIN output:

  • Alice, Engineering
  • Bob, Marketing
  • Carol, NULL
  • NULL, Finance

The pattern is mechanical once you see it. Left protects the left. Right protects the right. Full protects both. Inner protects neither. If you can produce these four grids from the same tiny dataset in an interview, you've demonstrated the concept better than any definition could. The SQL Server documentation on outer joins confirms this exact semantics for all three outer join variants.

Stop the WHERE clause from quietly undoing your outer join

Why the filter feels harmless and then ruins the answer

This is the most reliable trap in SQL join interview questions. The join runs first and preserves the unmatched rows with NULLs. Then the WHERE clause runs — and it silently eliminates every row where the filtered column is NULL. The outer join did its job. The WHERE clause undid it immediately afterward.

The structural reason candidates miss this: they think of WHERE as a filter on the source data, not as a post-join filter on the result set. But WHERE runs after the join. By the time it executes, the NULLs are already there — and a condition like `WHERE d.name = 'Engineering'` will exclude every NULL row because NULL is not equal to anything.

What this looks like in practice

Expected (wrong) answer from a candidate who didn't think about WHERE: three rows, with Carol showing NULL. Actual output: one row — Alice/Engineering. The WHERE clause filtered out Bob (Marketing doesn't equal Engineering) and Carol (NULL doesn't equal Engineering). The LEFT JOIN is now behaving exactly like an INNER JOIN with an extra filter.

The interview-safe way to explain the difference

ON and WHERE in joins serve different purposes. The `ON` clause defines the join condition — it runs during the join and determines which rows match. The `WHERE` clause filters the already-joined result set. For inner joins, this distinction doesn't change the output. For outer joins, it's everything.

If you want to filter on the right table's columns while preserving unmatched left rows, move the filter into the `ON` clause: `ON e.dept_id = d.dept_id AND d.name = 'Engineering'`. Now Carol still appears with NULLs, because the condition is evaluated during matching, not after. This distinction — ON vs WHERE in joins — is the single most common point where a candidate who "knows joins" still gives the wrong output in an interview.

Use ON and USING like someone who knows what the output will look like

ON gives you control; USING gives you shorthand

`ON` lets you specify any join condition, including conditions where the column names differ between tables. `USING` is shorthand for the case where the join column has the same name on both sides — it deduplicates that column in the output. With `ON`, both `e.dept_id` and `d.dept_id` can appear as separate columns. With `USING(dept_id)`, only one `dept_id` column appears in the result.

This matters in interviews because `USING` changes the output shape in a way that surprises candidates who haven't used it. If you `SELECT *` with `USING`, you get fewer columns than you'd expect from `ON`.

What this looks like in practice

The USING version eliminates the duplicate `dept_id` column. In a `SELECT *` scenario, the column count is different. Interviewers who ask about `ON` vs `USING` are testing whether you know this output difference, not just whether you know the syntax shorthand. The PostgreSQL USING documentation explicitly describes the column-merging behavior and is worth reading once to make the distinction concrete.

Know the dialect gotchas before the interviewer does

RIGHT JOIN is common enough to know, not common enough to depend on

Many SQL teams avoid RIGHT JOIN in production code because it makes queries harder to read — the mental model of "left is primary, right is secondary" is deeply ingrained. But interviewers still ask about it because it tests whether you understand mirror-image row retention or whether you just memorized LEFT JOIN and assumed the rest. The answer: RIGHT JOIN is LEFT JOIN with the tables swapped. Every row from the right table survives. Unmatched left rows are dropped.

If an interviewer asks you to rewrite a RIGHT JOIN as a LEFT JOIN (a common follow-up), the answer is to swap the table order in the FROM and JOIN clauses and change RIGHT to LEFT.

FULL OUTER JOIN is the one that gets awkward in some engines

FULL OUTER JOIN support varies by dialect in ways that matter for interview conversations. PostgreSQL and SQL Server support it natively. MySQL did not support FULL OUTER JOIN until relatively recently, and SQLite still does not support it directly — the standard workaround is a UNION of a LEFT JOIN and a RIGHT JOIN with deduplication logic.

Knowing this doesn't mean memorizing version numbers. It means being able to say: "FULL OUTER JOIN is standard SQL, but MySQL has historically lacked native support — in that environment I'd use a UNION of LEFT and RIGHT joins to get the same result." That answer signals real-world experience, not just textbook knowledge.

What this looks like in practice

When the interviewer specifies a dialect, adjust your answer:

  • PostgreSQL: FULL OUTER JOIN works natively. Use it directly.
  • SQL Server: FULL OUTER JOIN works natively. Syntax is identical to the standard.
  • MySQL 8.0+: FULL OUTER JOIN is still not natively supported. Use `LEFT JOIN UNION RIGHT JOIN` with a WHERE clause to exclude duplicates.
  • SQLite: No FULL OUTER JOIN. Same UNION workaround applies.

The PostgreSQL JOIN documentation and SQL Server JOIN reference both confirm native FULL OUTER JOIN support with standard syntax.

The 10 mistakes I see in interviews

Mistake 1–3: confusing match logic, row retention, and output order

Mistake 1: treating join type and match condition as the same thing. The join type (INNER, LEFT, RIGHT, FULL) controls which unmatched rows survive. The `ON` condition controls what counts as a match. These are independent decisions, and conflating them leads to wrong output predictions — especially when the match condition is non-obvious.

Mistake 2: assuming row order in the output. SQL does not guarantee output row order without an `ORDER BY`. Candidates who predict output in a specific order and then defend that order when challenged are revealing a gap. The rows are correct; the sequence is not promised.

Mistake 3: forgetting that multiple matches multiply rows. One left-side row matching three right-side rows produces three output rows. This is the correct behavior, not a bug — but candidates who haven't internalized it will give wrong row counts on one-to-many join questions.

Mistake 4–7: forgetting NULLs, misusing WHERE, and guessing the wrong side

Mistake 4: not accounting for NULLs in the output. Outer joins produce NULLs for unmatched columns. If your predicted output doesn't include NULLs where they belong, the answer is wrong — even if the matched rows are correct.

Mistake 5: filtering on a right-table column in WHERE after a LEFT JOIN. As covered above, this silently converts the outer join to inner join behavior. It's the single most common SQL join interview question trap and the one most candidates only recognize after they've made the mistake in production.

Mistake 6: guessing which side is preserved without reading the query. "Left" and "right" refer to the table's position in the query, not any semantic property of the data. Candidates who say "the left join keeps the more important table" are guessing, and interviewers notice immediately.

Mistake 7: assuming FULL OUTER JOIN is universally supported. Saying "just use FULL OUTER JOIN" without acknowledging dialect constraints signals that the candidate has only worked in one environment.

Mistake 8–10: overexplaining, skipping the tiny-table walkthrough, and never checking dialect assumptions

Mistake 8: leading with the definition instead of the output. When an interviewer shows you two tables and asks what the query returns, they want the output. Starting with "well, a LEFT JOIN is defined as..." wastes 30 seconds and signals you're stalling. Lead with the rows.

Mistake 9: skipping the row-by-row walkthrough under pressure. The tiny-table drill feels slow, but it's faster than getting the answer wrong and having to backtrack. Candidates who skip it to appear confident often produce wrong output counts. Candidates who do it out loud demonstrate structured thinking, which is exactly what the interviewer is evaluating.

Mistake 10: never asking about the dialect. If the question involves FULL OUTER JOIN or RIGHT JOIN and the interviewer hasn't specified the database, ask. "Are we in PostgreSQL or MySQL?" is a good question, not a sign of weakness. It shows you know that the answer depends on the environment.

How Verve AI Can Help You Ace Your Coding Interview With SQL Joins

The structural problem with SQL join prep is that most practice tools give you the answer immediately. You write the query, you run it, the output appears. There's no moment where you have to commit to a prediction before you see the result — which is exactly the moment that matters in a live technical interview. Drilling output prediction requires a tool that can respond to what you're actually reasoning through, not just grade your final query.

Verve AI Coding Copilot is built for that kind of live, adaptive practice. It reads your screen in real time — whether you're working through a join problem on LeetCode, HackerRank, or CodeSignal — and surfaces suggestions that respond to your current reasoning, not a canned hint. If you're mid-explanation on a LEFT JOIN output and you've missed the WHERE clause trap, Verve AI Coding Copilot can flag it before you commit to the wrong answer. The Secondary Copilot feature keeps your focus on one problem at a time, which matters when you're working through row-retention logic under time pressure and don't want to lose the thread. Because Verve AI Coding Copilot stays invisible during live sessions, it supports your thinking without becoming a crutch — you still have to reason through the output, but you're not doing it completely alone.

Conclusion

If you can take two four-row tables, trace every row through the join condition, and write down the exact output before running the query — you're ready for the join section of any SQL interview. Not because you memorized the right words, but because you built a working model of row retention that holds up under follow-up questions.

Keep the employees/departments dataset from this guide as your practice cheat sheet. Not to memorize the output, but to run the drill again before your next interview: predict first, then verify. Inner join, left, right, full outer — four queries, four outputs, one tiny dataset. That's the whole preparation. The interviewer isn't testing whether you know the vocabulary. They're testing whether you can think through the rows.

AC

Alex Chen

Interview Guidance

Ace your live interviews with AI support!

Get Started For Free

Available on Mac, Windows and iPhone