InterviewAlly

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.

February 19, 2026 · 14 min read

SQL · Database · Coding Interview

Database schema diagram with SQL queries on a screen

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.