Top 20 SQL Interview Questions for Software Engineers
SQL interviews are common even for backend and full-stack roles. Master 20 essential SQL questions covering JOINs, aggregations, window functions, and query optimization.
SQL is tested in interviews at nearly every tech company — not just for database roles, but for backend, full-stack, and data engineering positions. These SQL interview questions cover the patterns that appear most frequently, from basic JOINs to advanced window functions.
Basic Queries (Warm-up)
Q1: Find employees with salary above 100K
SELECT name, salary, department
FROM employees
WHERE salary > 100000
ORDER BY salary DESC;
Q2: Count unique departments
SELECT COUNT(DISTINCT department) as dept_count
FROM employees;
Q3: Find employees whose name starts with 'A'
SELECT name, email
FROM employees
WHERE name LIKE 'A%';
JOIN Questions
Q4: Get employee names with their department names
SELECT e.name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.id;
Q5: Find employees without a manager
SELECT e.name
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id
WHERE m.id IS NULL;
Q6: Find employees who earn more than their manager
SELECT e.name as employee, e.salary as emp_salary,
m.name as manager, m.salary as mgr_salary
FROM employees e
INNER JOIN employees m ON e.manager_id = m.id
WHERE e.salary > m.salary;
Aggregation & GROUP BY
Q7: Departments with average salary above 80K
SELECT department, AVG(salary) as avg_salary, COUNT(*) as emp_count
FROM employees
GROUP BY department
HAVING AVG(salary) > 80000
ORDER BY avg_salary DESC;
Q8: Highest paid employee in each department
SELECT department, name, salary
FROM employees e1
WHERE salary = (
SELECT MAX(salary)
FROM employees e2
WHERE e2.department = e1.department
);
Q9: Monthly revenue with running total
SELECT month,
revenue,
SUM(revenue) OVER (ORDER BY month) as running_total
FROM monthly_revenue;
Window Functions (Advanced)
Q10: Rank employees by salary within each department
SELECT name, department, salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) as salary_rank
FROM employees;
Key difference: RANK() skips numbers after ties. DENSE_RANK() doesn't. ROW_NUMBER() gives unique numbers.
Q11: Compare each month's revenue with previous month
SELECT month, revenue,
LAG(revenue, 1) OVER (ORDER BY month) as prev_month,
revenue - LAG(revenue, 1) OVER (ORDER BY month) as growth
FROM monthly_revenue;
Q12: Find the Nth highest salary
-- Find the 3rd highest salary
SELECT DISTINCT salary
FROM (
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) as rnk
FROM employees
) ranked
WHERE rnk = 3;
Subqueries & CTEs
Q13: Find duplicate emails
SELECT email, COUNT(*) as count
FROM users
GROUP BY email
HAVING COUNT(*) > 1;
Q14: Get department stats using CTE
WITH dept_stats AS (
SELECT department,
COUNT(*) as emp_count,
AVG(salary) as avg_salary,
MAX(salary) as max_salary
FROM employees
GROUP BY department
)
SELECT d.department_name, ds.*
FROM dept_stats ds
JOIN departments d ON ds.department = d.id
WHERE ds.emp_count > 5
ORDER BY ds.avg_salary DESC;
Q15: Find customers who have placed orders (EXISTS vs IN)
-- Using EXISTS (generally faster for large datasets)
SELECT c.name
FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o WHERE o.customer_id = c.id
);
-- Using IN
SELECT name
FROM customers
WHERE id IN (SELECT DISTINCT customer_id FROM orders);
Data Manipulation
Q16: Give a 10% raise to employees in the Engineering department
UPDATE employees
SET salary = salary * 1.10
WHERE department_id = (
SELECT id FROM departments WHERE department_name = 'Engineering'
);
Q17: Delete duplicate rows keeping the first occurrence
DELETE FROM users
WHERE id NOT IN (
SELECT MIN(id)
FROM users
GROUP BY email
);
Advanced Patterns
Q18: Find users who logged in for 3+ consecutive days
WITH numbered AS (
SELECT user_id, login_date,
login_date - INTERVAL '1 day' * ROW_NUMBER()
OVER (PARTITION BY user_id ORDER BY login_date) as grp
FROM logins
)
SELECT user_id, COUNT(*) as streak, MIN(login_date), MAX(login_date)
FROM numbered
GROUP BY user_id, grp
HAVING COUNT(*) >= 3;
Q19: Pivot rows to columns
SELECT product,
SUM(CASE WHEN quarter = 'Q1' THEN revenue ELSE 0 END) as Q1,
SUM(CASE WHEN quarter = 'Q2' THEN revenue ELSE 0 END) as Q2,
SUM(CASE WHEN quarter = 'Q3' THEN revenue ELSE 0 END) as Q3,
SUM(CASE WHEN quarter = 'Q4' THEN revenue ELSE 0 END) as Q4
FROM quarterly_sales
GROUP BY product;
Q20: Find the management hierarchy (Recursive CTE)
WITH RECURSIVE hierarchy AS (
SELECT id, name, manager_id, 1 as level
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id, h.level + 1
FROM employees e
INNER JOIN hierarchy h ON e.manager_id = h.id
)
SELECT name, level
FROM hierarchy
ORDER BY level, name;
Query Optimization Tips
- Use indexes on columns in WHERE, JOIN, and ORDER BY clauses
- Avoid SELECT * — only fetch columns you need
- Use EXISTS over IN for large subqueries
- Use EXPLAIN ANALYZE to understand query execution plans
- Avoid functions on indexed columns in WHERE clauses (breaks index usage)
Conclusion
These 20 SQL interview questions cover the patterns you'll encounter at most tech companies. Practice writing queries by hand (not just reading solutions), and focus on understanding when to use JOINs vs subqueries, window functions vs GROUP BY. For broader interview prep, check our FAANG preparation guide and system design guide which covers database design in depth.
Preparing for your next interview? Try InterviewAlly free — get AI-powered real-time assistance during your coding and SQL practice.