SQL is asked in interviews for developers, data analysts, data scientists, testers and MIS roles. These SQL interview questions cover SELECT, joins and aggregation for freshers, then subqueries, window functions, indexes, normalisation, query optimisation and classic SQL query problems for experienced candidates.
30 questions · Updated
Reading answers is not the same as saying them.Practise SQL questions out loud and get a score, what you missed and a model answer for each one.
Practise free with AISQL Interview Questions: 30 questions with model answers on this page.
Basic SQL interview questions
Fundamentals, definitions and simple scenarios. Good for freshers and warm-ups.
1. What are the types of SQL commands?
Answer flow · 4 steps
1
DDL (Data Definition Language) defines structure: CREATE, ALTER, DROP and TRUNCATE.
2
DML (Data Manipulation Language) changes data: INSERT, UPDATE and DELETE.
3
DQL queries data with SELECT.
4
DCL controls access with GRANT and REVOKE, and TCL manages transactions with COMMIT, ROLLBACK and SAVEPOINT.
2. What are the different types of joins?
Answer flow · 5 steps
1
INNER JOIN returns rows with matching values in both tables.
2
LEFT JOIN returns all rows from the left table and matches from the right, with NULLs where there is no match.
3
RIGHT JOIN is the reverse.
4
FULL OUTER JOIN returns all rows from both.
5
CROSS JOIN returns every combination, and a self join joins a table to itself, for example employees to their managers.
3. What is the difference between WHERE and HAVING?
Answer flow · 3 steps
1
WHERE filters rows before grouping and cannot use aggregate functions.
2
HAVING filters groups after GROUP BY and can use aggregates, such as HAVING COUNT(*) > 5.
3
For example, to find departments with more than five employees earning over 50,000, WHERE filters the salary and HAVING filters the count.
4. What is SQL, and what is a relational database?
SQL (Structured Query Language) is the standard language for creating, reading, updating and deleting data in relational databases. A relational database stores data in tables of rows and columns, with keys linking related tables, and a relational database management system such as MySQL, PostgreSQL, SQL Server or Oracle enforces data types, constraints and transactions.
5. How do GROUP BY and aggregate functions work?
Answer flow · 3 steps
1
GROUP BY collects rows with the same values in the chosen columns into groups, and aggregate functions calculate one value per group: COUNT, SUM, AVG, MIN and MAX.
2
For example, SELECT department, COUNT(*), AVG(salary) FROM employees GROUP BY department.
3
Every selected column must either be in the GROUP BY or inside an aggregate.
6. How do you sort and limit results?
Answer flow · 3 steps
1
ORDER BY sorts results by one or more columns, ascending by default or with DESC.
2
To return only some rows, MySQL and PostgreSQL use LIMIT and OFFSET, SQL Server uses TOP or OFFSET ... FETCH, and the SQL standard and Oracle use FETCH FIRST n ROWS ONLY.
3
Without ORDER BY, the order of rows is not guaranteed.
7. What does DISTINCT do?
Answer flow · 3 steps
1
DISTINCT removes duplicate rows from the result, considering all selected columns together, so SELECT DISTINCT city FROM customers returns each city once.
2
COUNT(DISTINCT city) counts unique values.
3
On large tables DISTINCT requires sorting or hashing, so GROUP BY or a better query design is sometimes clearer.
8. How do you handle NULL values?
Answer flow · 3 steps
1
NULL means unknown or missing, so comparisons with = or <> never match it; use IS NULL and IS NOT NULL.
2
Any arithmetic with NULL gives NULL, and aggregate functions ignore NULLs (COUNT(column) skips them, COUNT(*) does not).
3
COALESCE(phone, 'Not given') returns the first non-null value, and NULLIF(a, b) returns NULL when two values are equal, which avoids division by zero.
9. What constraints can you define on a table?
NOT NULL requires a value, UNIQUE prevents duplicates, PRIMARY KEY uniquely identifies each row, FOREIGN KEY enforces links to another table, CHECK validates a condition such as price > 0, and DEFAULT supplies a value when none is given. Constraints keep data correct at the database level, even if application code has bugs.
10. What is the difference between UNION and UNION ALL?
Answer flow · 5 steps
1
Both combine the results of two queries with the same number and types of columns.
2
UNION removes duplicate rows, which requires extra sorting or hashing.
3
UNION ALL keeps every row and is faster.
4
Use UNION ALL unless you specifically need duplicates removed.
5
INTERSECT and EXCEPT return common rows or rows only in the first query.
11. How do LIKE and wildcards work?
LIKE matches text patterns: % matches any number of characters and _ matches exactly one, so name LIKE 'Ra%' finds names starting with Ra, and LIKE '_a%' finds names whose second letter is a. A pattern starting with % cannot use a normal index, so it is slow on large tables; full-text search is better for searching inside text. PostgreSQL has ILIKE for case-insensitive matching.
Intermediate SQL interview questions
Applied problems, trade-offs and questions about your own projects.
12. What is the difference between DELETE, TRUNCATE and DROP?
Answer flow · 3 steps
1
DELETE removes selected rows using a WHERE clause, logs each row, fires triggers and can be rolled back.
2
TRUNCATE removes all rows quickly, resets identity counters and usually cannot be rolled back in some databases (MySQL), though it can in PostgreSQL and SQL Server within a transaction.
3
DROP removes the whole table including its structure.
13. How do you find the second highest salary?
Answer flow · 4 steps
1
One way is SELECT MAX(salary) FROM employees WHERE salary < (SELECT MAX(salary) FROM employees).
2
A more general way for the Nth highest uses a window function: SELECT salary FROM (SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk FROM employees) t WHERE rnk = 2.
3
DENSE_RANK handles ties correctly.
4
LIMIT 1 OFFSET 1 on distinct salaries also works in MySQL and PostgreSQL.
14. What are window functions?
Window functions calculate across a set of related rows without collapsing them into one row like GROUP BY does. Examples are ROW_NUMBER, RANK and DENSE_RANK for ranking, SUM() OVER for running totals, LAG and LEAD to compare with previous or next rows, and AVG() OVER (PARTITION BY department) to compare each employee with their department average.
15. What is the difference between a primary key, a unique key and a foreign key?
Answer flow · 3 steps
1
A primary key uniquely identifies each row, cannot be NULL, and a table has only one.
2
A unique key also enforces uniqueness but allows NULLs (how many depends on the database), and a table can have several.
3
A foreign key references a primary or unique key in another table to enforce referential integrity, so you cannot add an order for a customer who does not exist.
16. What is normalisation? Explain 1NF, 2NF and 3NF.
Answer flow · 4 steps
1
Normalisation organises tables to reduce duplicate data and update anomalies.
2
First normal form: each column holds atomic values and there are no repeating groups.
3
Second normal form: in 1NF and every non-key column depends on the whole primary key, not part of a composite key.
4
Third normal form: in 2NF and non-key columns do not depend on other non-key columns, so customer city belongs in the customers table, not in orders.
17. What is the difference between a subquery and a correlated subquery?
Answer flow · 3 steps
1
A subquery is a query inside another query, used in WHERE, FROM or SELECT, and an independent one runs once, such as finding employees in departments located in Pune.
2
A correlated subquery refers to columns of the outer query, so it is evaluated for each outer row, such as finding employees earning more than their own department's average.
3
Correlated subqueries can be slow and are often rewritten as joins or window functions.
18. What is a view?
Answer flow · 4 steps
1
A view is a saved query that behaves like a virtual table.
2
It simplifies complex joins, hides sensitive columns from some users and provides a stable interface when tables change.
3
A normal view runs its query each time it is used.
4
A materialized view stores the result physically for speed and must be refreshed.
19. What is the difference between a stored procedure and a function?
Answer flow · 3 steps
1
A stored procedure is precompiled SQL logic called with CALL or EXEC; it can perform inserts and updates, manage transactions and return multiple result sets.
2
A user-defined function returns a single value or a table, can be used inside SELECT statements, and usually cannot change data.
3
Business logic in procedures is fast but harder to version and test than application code.
20. What are transactions and ACID properties?
A transaction groups statements into one unit that either fully succeeds with COMMIT or is undone with ROLLBACK, such as debiting one account and crediting another. ACID means Atomicity (all or nothing), Consistency (data always satisfies rules and constraints), Isolation (concurrent transactions do not interfere) and Durability (committed data survives crashes).
21. How does the CASE expression work?
CASE adds conditional logic inside a query, similar to if/else: CASE WHEN score >= 75 THEN 'Distinction' WHEN score >= 40 THEN 'Pass' ELSE 'Fail' END. It is used to create categories, apply conditional aggregation such as SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END), and custom sort orders.
22. How do you find duplicate rows?
Answer flow · 3 steps
1
Group by the columns that define a duplicate and keep groups with more than one row: SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1.
2
To see or delete the extra rows while keeping one, number rows with ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) and remove those with a number greater than 1.
3
Then add a unique constraint to prevent new duplicates.
High level SQL interview questions
System design, deep internals, leadership and tough follow-ups.
23. What are indexes, and when can they hurt?
Answer flow · 3 steps
1
An index, usually a B-tree, lets the database find rows without scanning the whole table, speeding up WHERE, JOIN and ORDER BY.
2
Composite index column order matters: an index on (city, age) helps queries filtering by city, but not by age alone.
3
Indexes slow down inserts, updates and deletes and use storage, so I index columns that are queried often and selective, and remove unused ones.
24. How do you optimise a slow SQL query?
I read the execution plan with EXPLAIN or EXPLAIN ANALYZE to see full table scans, bad join orders or wrong row estimates. Then I add or adjust indexes, select only needed columns instead of SELECT *, avoid functions on indexed columns in WHERE, replace correlated subqueries with joins, filter early, paginate with keyset pagination for large offsets, and keep statistics up to date.
25. What are CTEs, and what is a recursive CTE?
A Common Table Expression, defined with WITH, names a temporary result set so complex queries can be split into readable steps. A recursive CTE references itself to walk hierarchies, such as an organisation chart or category tree: an anchor query selects the top level, and a recursive part joins back to find children until no more rows are found.
26. What are transaction isolation levels, and which anomalies do they prevent?
Read Committed prevents dirty reads but allows non-repeatable reads (a row changes between two reads).
3
Repeatable Read prevents those but may allow phantom reads (new rows appear in a range).
4
Serializable prevents all of them, as if transactions ran one at a time.
5
Higher isolation means more locking or retries, so most systems use Read Committed or Repeatable Read.
27. In what order is a SQL query logically executed?
Answer flow · 3 steps
1
FROM and JOIN first, then WHERE, GROUP BY, HAVING, SELECT (including window functions), DISTINCT, ORDER BY and finally LIMIT or OFFSET.
2
This explains why you cannot use a SELECT alias in WHERE but can in ORDER BY, and why aggregates belong in HAVING rather than WHERE.
3
The database optimiser may physically execute steps differently, but the results must match this order.
28. When would you denormalise a database?
Answer flow · 3 steps
1
Denormalisation deliberately duplicates data to make reads faster, for example storing an order total or a customer name on the order, or keeping summary tables for dashboards.
2
It suits read-heavy systems and reporting, where joins across many large tables are too slow.
3
The cost is extra storage and the need to keep copies in sync, using triggers, application logic or scheduled jobs.
29. What is the difference between EXISTS, IN and JOIN?
Answer flow · 5 steps
1
IN checks whether a value is in a list or subquery result.
2
EXISTS checks whether a subquery returns any row and can stop at the first match, which suits correlated checks such as customers who have placed an order.
3
JOIN combines rows and can create duplicates if the relationship is one-to-many.
4
NOT IN behaves unexpectedly if the subquery returns NULL, so NOT EXISTS is safer.
5
Modern optimisers often produce similar plans.
30. What are triggers, and what are their risks?
Answer flow · 3 steps
1
A trigger is code that runs automatically before or after INSERT, UPDATE or DELETE on a table, used for audit logs, enforcing complex rules or maintaining derived data.
2
The risks are hidden behaviour that developers do not expect, slower writes, harder debugging and cascading effects between triggers.
3
I use them sparingly, mainly for auditing, and keep business logic in the application.
SQL machine coding round questions
Tasks you build live in 30 to 60 minutes. What interviewers look for, plus a compact solution to compare with yours.
Find the top 3 highest-paid employees in each department.
A very common window-function question. DENSE_RANK keeps ties; use ROW_NUMBER if exactly three rows per department are required.
SELECT department_id, name, salary
FROM (
SELECT department_id, name, salary,
DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk <= 3
ORDER BY department_id, salary DESC;
Find employees who earn more than their manager.
Tests self joins. Join the employees table to itself, matching each employee to their manager.
SELECT e.name AS employee, e.salary, m.name AS manager, m.salary AS manager_salary
FROM employees e
JOIN employees m ON e.manager_id = m.id
WHERE e.salary > m.salary;
Find customers who have never placed an order.
Checks outer joins or NOT EXISTS. Both work; NOT EXISTS avoids the NULL trap of NOT IN.
-- Using a LEFT JOIN
SELECT c.id, c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;
-- Using NOT EXISTS
SELECT c.id, c.name
FROM customers c
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);
Calculate monthly revenue and month-over-month growth.
Combines aggregation, a CTE and LAG. Explain how you handle the first month, which has no previous value.
WITH monthly AS (
SELECT DATE_TRUNC('month', order_date) AS month, SUM(amount) AS revenue
FROM orders
GROUP BY 1
)
SELECT month, revenue,
ROUND(100.0 * (revenue - LAG(revenue) OVER (ORDER BY month))
/ NULLIF(LAG(revenue) OVER (ORDER BY month), 0), 1) AS growth_pct
FROM monthly
ORDER BY month;
Ready to test yourself?Pick your topics and level, answer by voice or text, and get instant feedback. Free.