Skip to main content

Interview questions by language

SQL interview questions

Joins, aggregation, window functions, indexes, and query optimisation.

What it really tests

Inside a SQL interview

A SQL interview is usually hands-on: you are given a schema and asked to write queries, escalating from simple filters to multi-table joins, aggregation, and window functions. Interviewers are checking three things: can you express the business question correctly in set-based logic, do you understand how the engine will execute your query, and do you reach for the right tool (a window function rather than a self-join, a CTE rather than a nested subquery) to keep the query readable and fast. SQL is declarative, so the seniority signal is knowing what the optimiser does with what you wrote.

The conceptual backbone is joins and grouping. You must be fluent in INNER vs LEFT vs FULL joins and what a join does to row counts, and you must understand the difference between WHERE (filters rows before grouping) and HAVING (filters groups after aggregation). A surprising number of candidates lose the offer on a subtle LEFT JOIN that silently drops rows because a filter on the right table was placed in WHERE instead of the ON clause.

The advanced tier is window functions and performance. Window functions (ROW_NUMBER, RANK, LAG/LEAD, running totals with SUM OVER) let you compute per-row analytics without collapsing rows, and they are the single most common 'separates juniors from seniors' SQL topic. On performance, you should be able to explain what an index is, why a query on an unindexed column is slow, what a covering index is, and how to read an execution plan to find a full table scan.

Where it matters

SQL is tested in almost every data, analytics, and backend interview across the US and EU, and is the core screen for data-engineer and analytics-engineer roles; it is the most broadly applicable technical skill on this list.

The map

Core areas interviewers drill

Joins and set logic

INNER vs LEFT vs FULL, how joins affect row counts, and the ON-vs-WHERE trap that silently drops rows in outer joins.

Aggregation

GROUP BY, the WHERE-vs-HAVING distinction, and aggregate functions. The most common source of subtle wrong answers.

Window functions

ROW_NUMBER, RANK, LAG/LEAD, running totals, and PARTITION BY. The top 'senior SQL' signal because they replace clumsy self-joins.

Indexes and optimisation

How indexes speed lookups, covering indexes, and reading an execution plan to spot a full table scan or a missing index.

Question bank

SQL questions and answers

12 questions

The questions that come up most often, each with a sample answer you can adapt into your own words. Read them out loud until the explanation feels natural.

What is the difference between an INNER JOIN and a LEFT JOIN?

Fundamentals

An INNER JOIN returns only rows that match in both tables. A LEFT JOIN returns every row from the left table and the matching rows from the right, filling NULLs where there is no match. Use a LEFT JOIN when you need to keep all left-side rows regardless of whether a related right-side row exists, for example all customers including those with no orders.

What is the difference between WHERE and HAVING?

Intermediate

WHERE filters individual rows before grouping and cannot reference aggregate functions. HAVING filters groups after GROUP BY and can use aggregates like COUNT or SUM. So you use WHERE to restrict which rows enter the aggregation and HAVING to restrict which aggregated groups appear in the result.

What is a window function and when would you use one?

Advanced

A window function computes a value across a set of rows related to the current row without collapsing them into one, using the OVER clause. Examples are ROW_NUMBER() for ranking within a partition, LAG/LEAD to access previous or next rows, and SUM(...) OVER (...) for running totals. Use one whenever you need per-row analytics like 'each employee's salary rank within their department' that a GROUP BY would flatten away.

How would you find the second-highest salary?

Intermediate

The cleanest modern approach uses a window function: SELECT salary FROM (SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk FROM employees) t WHERE rnk = 2. DENSE_RANK handles ties correctly. A classic alternative is a correlated subquery or SELECT MAX(salary) FROM employees WHERE salary < (SELECT MAX(salary) FROM employees), though that does not generalise to the Nth value as cleanly.

What is an index and what is the tradeoff?

Advanced

An index is an auxiliary data structure (usually a B-tree) that lets the engine find rows by a column's value without scanning the whole table, turning a lookup from O(n) into roughly O(log n). The tradeoff is that indexes consume storage and slow down writes, because every INSERT, UPDATE, and DELETE must also maintain the index. So you index columns used in WHERE, JOIN, and ORDER BY, but do not index everything.

What is the difference between DELETE, TRUNCATE, and DROP?

Intermediate

DELETE removes rows (optionally filtered by WHERE), is logged row by row, and can be rolled back. TRUNCATE removes all rows quickly by deallocating pages, is minimally logged, resets identity counters, and cannot be filtered. DROP removes the entire table including its structure. In short: DELETE for selective removal, TRUNCATE to empty a table fast, DROP to delete the table itself.

What does a primary key guarantee versus a unique constraint?

Fundamentals

Both enforce uniqueness, but a primary key additionally disallows NULLs and there can be only one per table; it is the canonical row identifier and typically the clustered index. A unique constraint enforces uniqueness on a column or set of columns, permits one NULL (in most databases), and you can have several per table. Use the primary key for the row's identity and unique constraints for other naturally unique columns like email.

How do you read an execution plan to optimise a slow query?

Advanced

Run EXPLAIN (or EXPLAIN ANALYZE) and look for the expensive operations: a full table scan or sequential scan on a large table usually means a missing index on the filtered or joined column. Check the join order and method (hash vs nested loop) and the estimated vs actual rows, since a big mismatch points to stale statistics. The common fixes are adding or adjusting an index, rewriting to avoid functions on indexed columns, and updating table statistics.

What is a CTE and when would you use one over a subquery?

Intermediate

A common table expression, introduced with WITH, names an intermediate result so the main query reads like a pipeline of steps. Functionally it overlaps with a derived-table subquery, but a CTE is more readable, can be referenced more than once, and is the only way to express recursion, such as walking an org chart or a category tree. Interviewers often accept either but read CTE usage as a sign you write SQL other people have to maintain. Note that some engines materialise CTEs while others inline them, which can matter for performance.

SQL
WITH monthly AS (
  SELECT customer_id,
         DATE_TRUNC('month', order_date) AS month,
         SUM(amount) AS total
  FROM orders
  GROUP BY customer_id, DATE_TRUNC('month', order_date)
)
SELECT customer_id, AVG(total) AS avg_monthly_spend
FROM monthly
GROUP BY customer_id;

How do you get the latest row per group?

Advanced

The standard pattern is ROW_NUMBER() partitioned by the group and ordered by the timestamp descending, then filtering to row number 1 in an outer query or CTE. It expresses 'each customer's most recent order' in one pass and generalises to top-N by changing the filter. Alternatives exist, like a join against a MAX subquery or DISTINCT ON in PostgreSQL, but the window-function version is portable and handles ties predictably if you switch to RANK. This is among the most common practical SQL interview tasks.

SQL
WITH ranked AS (
  SELECT o.*,
         ROW_NUMBER() OVER (
           PARTITION BY customer_id
           ORDER BY order_date DESC
         ) AS rn
  FROM orders o
)
SELECT * FROM ranked WHERE rn = 1;

What is the difference between UNION and UNION ALL?

Fundamentals

Both stack the results of two queries with compatible columns. UNION removes duplicate rows across the combined result, which requires sorting or hashing everything and costs accordingly. UNION ALL keeps every row, duplicates included, and is therefore cheaper. The interview signal is defaulting to UNION ALL unless you specifically need deduplication, and being able to say why: asking the engine to dedupe millions of rows you already know are distinct is a silent performance bug that shows up in real pipelines.

What is a transaction, and what do the ACID properties mean?

Intermediate

A transaction groups statements so they succeed or fail as a unit: BEGIN, then COMMIT to keep the changes or ROLLBACK to discard them. ACID summarises the guarantees. Atomicity: all or nothing. Consistency: the database moves between valid states, with constraints holding. Isolation: concurrent transactions do not see each other's half-done work, tunable via isolation levels. Durability: once committed, changes survive a crash. The classic example is a money transfer, where debiting one account and crediting another must never be split, and a strong answer also names the isolation-level tradeoffs.

Avoid these

SQL gotchas that cost candidates

  • Filtering the right table of a LEFT JOIN in WHERE, which silently turns it into an INNER JOIN.
  • Using HAVING where WHERE belongs (or vice versa) and getting the wrong row set.
  • Forgetting that COUNT(column) ignores NULLs while COUNT(*) does not.
  • Wrapping an indexed column in a function in WHERE, which prevents the index from being used.

The plan

How to prepare for a SQL interview

  • Practise multi-table joins and articulate how each join type changes row counts.
  • Master window functions; they are the highest-leverage SQL interview topic.
  • Be able to explain indexes, covering indexes, and the write-cost tradeoff.
  • Walk through reading an EXPLAIN plan to find a missing index or table scan.

Last reviewed by the site editor: June 2026

Turn prep into an offer

Language fluency gets you through the screen. Pair it with the coding interview patterns, rehearse the behavioral round with worked STAR answers, and when the offer comes, check it is competitive with the salary comparison tool.