Skip to the solution
HardDSA13 min read

What is a LATERAL join?

970 views

The problem

Question presented to candidate: "What does the LATERAL keyword do in a FROM clause? Show me a query that needs it, and tell me how it differs from a normal join to a subquery."

What a strong answer should cover:

  • A normal derived table in FROM cannot reference other tables of the same FROM clause; LATERAL lets it reference items to its left
  • Semantics: the lateral subquery is evaluated once per row of the left side, like a correlated subquery that can return many rows and many columns
  • CROSS JOIN LATERAL drops left rows with no result; LEFT JOIN LATERAL ... ON true keeps them with NULLs
  • Typical uses: top-N / latest-row per group with ORDER BY ... LIMIT, several columns from one lookup, reusing a computed expression, set-returning functions (implicitly lateral)
  • Plans: usually a Nested Loop that runs the inner side once per outer row, fast when an index serves the inner lookup
  • Engine support: PostgreSQL and MySQL 8.0.14+ spell it LATERAL, SQL Server uses CROSS APPLY / OUTER APPLY, SQLite has no LATERAL

Code / implementation expected: Yes β€” a LATERAL subquery that returns each customer's latest order, and the LEFT JOIN LATERAL variant.

Schema used by the examples:

  • lateral

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

13 min read Β· 11 sections

Run the code

Edit the query and run it against the tables for this question.

CROSS JOIN LATERAL: each customer with their most recent order
SELECT c.name, o.id AS order_id, o.ordered_at, o.amount
FROM customers AS c
CROSS JOIN LATERAL (
  SELECT id, ordered_at, amount
  FROM orders
  WHERE orders.customer_id = c.id      -- refers to c, defined to the left
  ORDER BY ordered_at DESC
  LIMIT 1
) AS o
ORDER BY c.name;
LEFT JOIN LATERAL ... ON true keeps customers without orders
SELECT c.name, o.order_id, o.ordered_at, o.amount
FROM customers AS c
LEFT JOIN LATERAL (
  SELECT id AS order_id, ordered_at, amount
  FROM orders
  WHERE orders.customer_id = c.id
  ORDER BY ordered_at DESC
  LIMIT 1
) AS o ON true
ORDER BY c.name;
The plan: a Nested Loop that runs the inner Limit once per customer
EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT c.name, o.amount
FROM customers AS c
CROSS JOIN LATERAL (
  SELECT amount FROM orders
  WHERE orders.customer_id = c.id
  ORDER BY ordered_at DESC
  LIMIT 1
) AS o;
SQLSQLite has no LATERAL: the same answer with correlated scalar subqueries

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 71 of 82 in SQL

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All SQL questions
Up nextHard

SKIP LOCKED for job queues β€” how do you build a concurrent queue without race conditions?

Continue