Question presented to candidate: "For each customer, we want their three biggest orders, for a dashboard that shows a page of customers at a time. How would you write that in PostgreSQL so it stays fast when the orders table has millions of rows?"
What a strong answer should cover:
CROSS JOIN LATERAL (SELECT ... WHERE o.customer_id = c.id ORDER BY amount DESC, id DESC LIMIT 3): one small top-3 query per customer- The index that makes it fast:
(customer_id, amount DESC, id DESC), so each inner query reads exactly three index entries (PostgreSQL showsLimitover anIndex Only Scanwithloops= number of customers) - A deterministic tie-breaker, and the alternative
FETCH FIRST 3 ROWS WITH TIES(PostgreSQL 13+) when tied orders should all be shown LEFT JOIN LATERAL ... ON truewhen customers without orders must still appear- The trade-off against
ROW_NUMBER() OVER (PARTITION BY customer_id ...): the window version reads every order, LATERAL reads three per customer; which wins depends on rows per customer and how many customers you need - Portability: SQLite has no LATERAL, SQL Server uses
CROSS APPLYwithTOP (3), MySQL supports LATERAL from 8.0.14
Clarifying questions expected:
- "Biggest" by amount or "latest" by date, and what happens with ties at third place?
- Should customers with no orders appear, and do we need all customers or a page of them?
Code / implementation expected: Yes — the LATERAL query with the supporting index, ideally with the plan and the window-function alternative.
Schema used by the examples: