Tell me about a SQL project you worked on. What was the data model, and what was the hardest query in it?
Most candidates answer this as a story about the company. Interviewers want a story about the data. Use a fixed four-part shape and it stays under two minutes: the domain and its grain, the schema you built and why, the hardest query and what made it hard, and the one measurable outcome.
For the schema, name the entities and the key decisions rather than listing tables. "Orders and order lines, with a products table and a denormalised product snapshot on the line so historical invoices do not change when the catalogue does" tells an interviewer far more than "a normalised schema with foreign keys". The denormalisation is the interesting decision, and it is the kind of decision the role exists to make.
For the hardest query, pick one that has a real trade-off behind it — a reporting query over millions of rows, a dedup job, a slowly-changing dimension lookup, a reconciliation between two sources. Then say what made it hard, what you tried, and why the final shape works. An interviewer's second question is always about the trade-off you chose, so name it yourself before they ask.
For the outcome, give one number with its denominator and its timeframe. "Cut the nightly reconciliation from 40 minutes to 90 seconds" is checkable and specific. "Improved performance significantly" is noise. If you do not have a number, give a before-and-after shape instead: what the query did before, what it does now, and what that made possible for the people using it.
Close by naming what you would do differently. Every interviewer knows a project has rough edges, and a candidate who can say "I would have versioned that dimension table from the start instead of backfilling" has shown the judgement the job needs. The failure mode to avoid is presenting a project where everything went perfectly; it reads as a story you have rehearsed rather than one you worked on.
Here is the same thing as runnable code:
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name VARCHAR(120) NOT NULL
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL REFERENCES customers(id),
placed_on TEXT NOT NULL
);
CREATE TABLE order_lines (
id INTEGER PRIMARY KEY,
order_id INTEGER NOT NULL REFERENCES orders(id),
product_name VARCHAR(120) NOT NULL,
quantity INTEGER NOT NULL,
unit_price_cents INTEGER NOT NULL
);
INSERT INTO customers (id, name) VALUES
(1, 'Ada Lovelace'),
(2, 'Grace Hopper');
INSERT INTO orders (id, customer_id, placed_on) VALUES
(1, 1, date('now', '-3 day')),
(2, 2, date('now', '-7 day')),
(3, 1, date('now', '-40 day'));
INSERT INTO order_lines (id, order_id, product_name, quantity, unit_price_cents) VALUES
(1, 1, 'Analytical Engine, printed edition', 1, 12000),
(2, 1, 'Punch card stock', 5, 250),
(3, 2, 'Compiler, manual volume', 2, 7500),
(4, 3, 'Legacy tape drive', 1, 45000);
SELECT o.id AS order_id,
o.placed_on,
c.name AS customer,
SUM(ol.quantity * ol.unit_price_cents) AS revenue_cents
FROM orders o
JOIN order_lines ol ON ol.order_id = o.id
JOIN customers c ON c.id = o.customer_id
WHERE o.placed_on >= date('now', '-30 day')
GROUP BY o.id, o.placed_on, c.name
ORDER BY revenue_cents DESC;