150+ SQL & MySQL Scenario-Based Interview Questions with Answers

150+ SQL & MySQL Scenario-Based Interview Questions
Interview preparation guide

150+ SQL & MySQL Scenario-Based Interview Questions

Learn to solve real database problems—not just memorize syntax. Practise joins, duplicates, subqueries, window functions, transactions, query tuning, and SQL validation scenarios asked in QA, SDET, backend, and data-focused interviews.

150+Interview scenarios
7 daysSuggested study plan
Hands-onQueries + mini quiz

Best for: QA Engineers, SDETs, Automation Engineers, Backend Developers, Data Analysts, and Automation Leads.

Jump to a topic

1. Start with a practice schema

Use these sample tables to practise the questions below. Examples use MySQL 8.0+ syntax.

CREATE TABLE departments (
  department_id INT PRIMARY KEY,
  department_name VARCHAR(100)
);

CREATE TABLE employees (
  employee_id INT PRIMARY KEY,
  employee_name VARCHAR(100),
  department_id INT,
  salary DECIMAL(10,2),
  manager_id INT,
  hire_date DATE,
  FOREIGN KEY (department_id)
    REFERENCES departments(department_id)
);

CREATE TABLE customers (
  customer_id INT PRIMARY KEY,
  customer_name VARCHAR(100),
  email VARCHAR(150),
  city VARCHAR(100)
);

CREATE TABLE orders (
  order_id INT PRIMARY KEY,
  customer_id INT,
  order_date DATETIME,
  amount DECIMAL(10,2),
  status VARCHAR(30),
  FOREIGN KEY (customer_id)
    REFERENCES customers(customer_id)
);

CREATE TABLE payments (
  payment_id INT PRIMARY KEY,
  order_id INT,
  payment_amount DECIMAL(10,2),
  payment_status VARCHAR(30),
  payment_date DATETIME
);
Practice tip: Before writing a query, clarify the business rule. For example, “duplicate payment” could mean two successful payments, repeated payment attempts, or multiple valid partial payments.

2. SQL fundamentals: questions 1–20

#ScenarioConcept
1Find employees earning more than ₹50,000.WHERE
2Find salaries between ₹40,000 and ₹80,000.BETWEEN
3Find employees whose names start with A.LIKE
4Find employees without a department.NULL / LEFT JOIN
5Find employees whose salary is missing.IS NULL
6List unique customer cities.DISTINCT
7Count all employees.COUNT
8Calculate average salary.AVG
9Find minimum and maximum salary.MIN / MAX
10Calculate total salary expense.SUM
11Count employees per department.GROUP BY
12Find departments with more than five employees.HAVING
13Find customers from Indore or Bhopal.IN
14Find employees hired during 2025.Date ranges
15Sort employees by salary descending.ORDER BY
16Return the five highest-paid employees.LIMIT
17Display missing salary as zero.COALESCE
18Display employee names in uppercase.UPPER
19Extract the year from a hire date.YEAR
20Find employees earning above company average.Subquery

Example: Employees earning above the company average

SELECT employee_name, salary
FROM employees
WHERE salary > (
  SELECT AVG(salary) FROM employees
);

Example: Find employees hired during 2025

SELECT employee_id, employee_name, hire_date
FROM employees
WHERE hire_date >= '2025-01-01'
  AND hire_date <  '2026-01-01';

Using a range can allow better use of an index on the date column than wrapping the column in YEAR().

3. JOIN scenarios: questions 21–35

#ScenarioApproach
21Display every order with its customer name.INNER JOIN
22Find customers who never ordered.LEFT JOIN + IS NULL
23Find orders whose customer is missing.LEFT JOIN from orders
24Show all customers, including those without orders.LEFT JOIN
25Display employee names and department names.JOIN
26Find employees without a valid department.LEFT JOIN
27Display each employee and their manager.Self join
28Find customers with more than three orders.JOIN + GROUP BY
29Display orders with payment details.Multi-table join
30Find orders with no payment record.NOT EXISTS
31Find customers with successful payments.JOIN + filter
32Show departments with zero employees too.LEFT JOIN
33Find employees in the same department as a given employee.Self join
34Find customers who ordered and paid.Multi-table joins
35Find customers with orders but no completed payment.NOT EXISTS

Example: Customers who never placed an order

SELECT c.customer_id, c.customer_name
FROM customers c
LEFT JOIN orders o
  ON c.customer_id = o.customer_id
WHERE o.order_id IS NULL;

Example: Employee and manager names

SELECT e.employee_name AS employee,
       m.employee_name AS manager
FROM employees e
LEFT JOIN employees m
  ON e.manager_id = m.employee_id;

Example: Orders with no payment record

SELECT o.order_id
FROM orders o
WHERE NOT EXISTS (
  SELECT 1
  FROM payments p
  WHERE p.order_id = o.order_id
);
Common trap: A filter on the right-side table in a LEFT JOIN’s WHERE clause can remove unmatched rows. Decide whether the filter belongs in ON or WHERE based on whether unmatched left-side rows must remain.

4. Duplicate records & data-quality scenarios: questions 36–55

Example: Find duplicate email addresses

SELECT email, COUNT(*) AS occurrences
FROM customers
WHERE email IS NOT NULL
GROUP BY email
HAVING COUNT(*) > 1;

Example: Return all customer rows with duplicate emails

SELECT c.*
FROM customers c
JOIN (
  SELECT email
  FROM customers
  WHERE email IS NOT NULL
  GROUP BY email
  HAVING COUNT(*) > 1
) d ON d.email = c.email;

Example: Find missing or blank emails

SELECT *
FROM customers
WHERE email IS NULL OR TRIM(email) = '';

Example: Find negative order amounts

SELECT *
FROM orders
WHERE amount < 0;

Example: Find payment amounts that differ from order amounts

This example assumes one successful payment should equal the order amount. If split or partial payments are allowed, aggregate successful payments first.

SELECT o.order_id,
       o.amount AS order_amount,
       p.payment_amount
FROM orders o
JOIN payments p ON p.order_id = o.order_id
WHERE p.payment_status = 'SUCCESS'
  AND p.payment_amount <> o.amount;

More practice questions

  1. Find duplicate rows based on customer name and city.
  2. Find duplicate orders for a customer on the same date—after confirming the business rule.
  3. Find orphan payment records.
  4. Find names with leading or trailing spaces.
  5. Find duplicate emails after normalizing case and whitespace.
  6. Find missing IDs in a sequence.
  7. Find orders with future dates.
  8. Identify malformed email addresses.
  9. Find records where created date is later than updated date.
  10. Validate mandatory columns across several tables.
  11. Compare source and target row counts.
  12. Identify repeated transactions caused by retries.
  13. Find values outside an approved status list.
  14. Detect inconsistent whitespace or capitalization in category fields.
  15. Find duplicates without a unique identifier.
  16. Design a safe deduplication process that retains the correct record.
  17. Find rows that violate a business-specific data rule.
  18. Identify unexpected NULL values in required fields.

5. Advanced SQL & window functions: questions 56–75

Second-highest distinct salary

SELECT MAX(salary) AS second_highest_salary
FROM employees
WHERE salary < (SELECT MAX(salary) FROM employees);

Top three distinct salary levels in each department

WITH ranked AS (
  SELECT employee_id, employee_name, department_id, salary,
         DENSE_RANK() OVER (
           PARTITION BY department_id
           ORDER BY salary DESC
         ) AS salary_rank
  FROM employees
  WHERE salary IS NOT NULL
)
SELECT *
FROM ranked
WHERE salary_rank <= 3;

Latest order for each customer

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

Running total of orders

SELECT order_id, order_date, amount,
       SUM(amount) OVER (
         ORDER BY order_date, order_id
         ROWS BETWEEN UNBOUNDED PRECEDING
                  AND CURRENT ROW
       ) AS running_total
FROM orders;

Compare each order with the customer’s previous order

SELECT customer_id, order_id, order_date, amount,
       LAG(amount) OVER (
         PARTITION BY customer_id
         ORDER BY order_date, order_id
       ) AS previous_amount
FROM orders;

Other advanced challenges

  1. Find employees whose salary equals their department’s maximum.
  2. Find the median salary.
  3. Calculate month-over-month sales percentage change.
  4. Find customers who ordered in every month of a quarter.
  5. Find products contributing to the first 80% of cumulative sales.
  6. Find employees earning more than every employee in another department.
  7. Find customers who ordered in January but not February.
Know the difference: ROW_NUMBER assigns a unique sequence; RANK leaves gaps after ties; DENSE_RANK does not leave gaps. Decide whether “top three” means three rows or three distinct values.

6. MySQL internals & performance: questions 76–90

#ScenarioWhat to discuss
76A query is slow despite an index.EXPLAIN, selectivity, statistics, access path
77A join unexpectedly returns duplicates.Join cardinality and one-to-many relationships
78An indexed date query scans too many rows.Sargability and date ranges
79Two users update the same balance.Transactions and row locks
80A multi-table update fails partway through.ROLLBACK and atomicity
81Two transactions wait on each other.Deadlocks and retry strategy
82Compare DELETE, TRUNCATE and DROP.Rows vs table; implicit commit
83A comparison involving NULL gives unexpected results.Three-valued logic
84Prevent duplicate email addresses.UNIQUE constraint
85Return the top ten rows after filtering.Clause semantics and ordering
86Choose a composite index.Column order and workload
87NOT IN unexpectedly returns no rows.NULL in subquery
88Investigate a deadlock.InnoDB status and Performance Schema
89Prevent a lost update.Locking or optimistic concurrency
90LIMIT returns different rows.Deterministic ORDER BY

Use EXPLAIN to inspect a query plan

EXPLAIN
SELECT *
FROM orders
WHERE customer_id = 1001;

Review the access type, selected key, estimated rows, join order, and extra operations. On supported MySQL versions, EXPLAIN ANALYZE executes the query and reports actual timing and row counts; use it cautiously for expensive queries.

DELETE vs TRUNCATE vs DROP

  • DELETE: removes selected rows and supports WHERE. Transactional rollback depends on the storage engine and transaction context.
  • TRUNCATE TABLE: removes all rows; in MySQL it is DDL and causes an implicit commit.
  • DROP TABLE: removes the table definition and its data.

Why can NOT IN fail with NULL?

SELECT customer_id
FROM customers
WHERE customer_id NOT IN (
  SELECT customer_id FROM orders
);

If the subquery contains NULL, comparisons can evaluate to UNKNOWN and exclude rows unexpectedly. NOT EXISTS is often a safer alternative.

7. SQL for QA & SDET interviews: questions 91–120

#ScenarioValidation focus
91API returns 100 customers but database has 105.Pagination, filters, authorization, timing
92Validate newly registered user data.Field-level assertions and unique test data
93Order API succeeds but no row is visible.Commit, async processing, environment, logs
94Ensure an order is not charged twice.Idempotency and payment business rules
95Reconcile order total with line items.Quantity, price, tax, discounts, rounding
96Verify database state after an update API.Before/after state and unchanged fields
97Validate a delete API.Soft delete vs physical delete
98Test rollback after a multi-step failure.Atomicity and related tables
99Compare source and target after migration.Counts, keys, fields, aggregates, hashes
100Find source rows missing from target.Anti-join / staged key comparison
101Registration passes but login fails.Stored state, activation, credentials flow
102API status is correct but stored value is wrong.Database assertion against request
103Order completed but payment failed.State consistency and workflow rules
104Validate refund across order, payment and balance.Reconciliation and transactions
105Retry creates duplicate records.Idempotency keys and uniqueness
106Validate audit timestamps.Time zone, precision, update rules
107Concurrent requests create the same customer.Unique constraints and race conditions
108Validate API pagination and sorting.Stable ordering and expected IDs
109Prevent access to another customer’s data.Authorization and tenant boundaries
110Validate a batch job processes eligible rows once.Eligibility, retries, idempotency
111Test foreign-key behavior.Parent/child integrity
112Test a stored procedure.Valid, invalid, boundary inputs
113Test a trigger that writes audit records.Side effects and transaction behavior
114Validate a scheduled job’s date range.Boundaries, time zones, cutoff times
115Test dirty, non-repeatable and phantom reads.Isolation levels
116Connection drops during a transaction.Rollback, retry, uncertain commit
117Test deadlock recovery.Retry handling and consistency
118Validate schema migration.Backward compatibility and data integrity
119Several users buy the last inventory item.Conditional update and locking
120Design reusable SQL assertions for automation.Connection management and test isolation

Example: Find orders without a successful payment

SELECT o.order_id
FROM orders o
WHERE NOT EXISTS (
  SELECT 1
  FROM payments p
  WHERE p.order_id = o.order_id
    AND p.payment_status = 'SUCCESS'
);

Example: Safe inventory decrement

UPDATE inventory
SET stock_quantity = stock_quantity - 1
WHERE product_id = 101
  AND stock_quantity > 0;

Check the affected-row count. A complete checkout should use a transaction for the inventory change and related order records. Also account for the case where the product ID does not exist.

QA interview framework: Explain the business rule, create controlled test data, run the action, query the database, assert expected values, test negative cases, and clean up safely. Never rely on row counts alone to prove data equality.

8. Transactions, constraints & schema design: questions 121–135

#ScenarioTopic
121Prevent duplicate registration emails.UNIQUE
122Prevent orders referencing missing customers.Foreign key
123Prevent a negative account balance.Constraint and transaction logic
124Undo updates after a failure.ROLLBACK
125Undo part of a transaction.SAVEPOINT
126Explain the role of COMMIT.Transaction lifecycle
127Choose isolation for a banking workflow.Isolation levels
128Prevent selling more stock than available.Conditional update and locks
129Compare primary and unique keys.Constraints
130Choose CHAR, VARCHAR, TEXT or numeric types.Data modeling
131Decide whether to normalize tables.Normalization
132Optimize a reporting workload.Denormalization trade-offs
133Add indexes without harming writes unnecessarily.Index trade-offs
134Record changes to customer records.Audit/history design
135Change schema while application is running.Safe migrations

Example: transaction pattern

START TRANSACTION;

UPDATE accounts
SET balance = balance - 500
WHERE account_id = 101
  AND balance >= 500;

-- Application must check affected rows.
-- Apply related updates only when valid.

COMMIT;
-- On a handled failure, use ROLLBACK instead.

For a transfer, debit and credit should happen in one transaction. Use InnoDB, validate affected-row counts, and design locking and retry behavior deliberately.

9. Tricky SQL output questions: 136–150

  1. Why does COUNT(*) differ from COUNT(email)?
  2. How do WHERE and HAVING differ?
  3. What happens when a scalar subquery returns multiple rows?
  4. Why can joining two one-to-many tables inflate totals?
  5. How do UNION and UNION ALL differ?
  6. When is EXISTS preferable to a JOIN?
  7. Why is salary = NULL incorrect?
  8. Why can GROUP BY queries fail with unrelated selected columns?
  9. How do ROW_NUMBER, RANK and DENSE_RANK differ?
  10. Why can a date filter miss records on the final day?
  11. Find the third occurrence of an event for each user.
  12. Find gaps in a sequence of dates.
  13. Why can OR conditions affect query performance?
  14. How can implicit type conversion affect indexes?
  15. Return the latest row per group when timestamps can tie.

COUNT(*) vs COUNT(email)

SELECT COUNT(*) AS total_rows,
       COUNT(email) AS rows_with_email
FROM customers;

COUNT(*) counts all rows. COUNT(email) excludes rows where email is NULL.

UNION vs UNION ALL

SELECT city FROM customers
UNION
SELECT city FROM suppliers;

UNION removes duplicate result rows; UNION ALL preserves them and is generally cheaper when duplicate removal is unnecessary.

10. Interactive practice tracker

Check off each challenge after solving it without help. Your progress is tracked in this page while it remains open.

0 of 15 completed

11. Quick knowledge-check quiz

Choose an answer for each question, then select Check my answers to see your score and explanations.

1. Which expression counts only rows where email is not NULL?
2. Which is often safer for finding rows with no match?
3. Which ranking function does not leave gaps after ties?
4. Which statement is true in MySQL?
5. How should you make a LIMIT query return a stable set of rows?

12. Seven-day SQL interview study plan

Day 1

SQL fundamentals

WHERE, aggregates, NULL, GROUP BY, HAVING.

Day 2

Joins & subqueries

INNER/LEFT JOIN, anti-joins, EXISTS, correlated subqueries.

Day 3

Advanced SQL

CTEs, ranking, running totals, LAG and LEAD.

Day 4

MySQL fundamentals

Indexes, constraints, data types, normalization.

Day 5

Transactions & performance

ACID, locks, deadlocks, EXPLAIN, isolation.

Day 6

QA database testing

API-to-DB checks, migration, reconciliation, concurrency.

Day 7

Mock interview

Solve 15–20 queries without assistance and explain trade-offs.

13. How to answer SQL interview questions confidently

  1. Clarify the rule: What does the business mean by “duplicate”, “latest”, or “successful”?
  2. Design the query: Identify tables, joins, filters, grouping and ordering.
  3. Cover edge cases: Check NULLs, ties, empty results, duplicates and date boundaries.
  4. Consider performance: Discuss indexes and validate the execution plan with EXPLAIN.
  5. Connect it to automation: Explain how your test reads data and asserts the result.
  6. Protect data: Use isolated test data, least-privilege access and safe cleanup.

Ready for your SQL interview?

Start with joins, duplicate detection, second-highest salary, top-N-per-group, EXISTS, window functions, transactions, query tuning, and API-to-database reconciliation. Practise explaining not only what your query does, but why it is correct and how it handles edge cases.

Challenge: Pick five questions today, write the queries from scratch, and explain each solution aloud as if you were in the interview.

Compatibility note: The interactive tracker and quiz use JavaScript. Some WordPress editors or security plugins strip inline scripts from post content. If that happens, keep the article markup in the post and add the script through an approved snippets plugin or your theme’s enqueued JavaScript. Avoid pasting untrusted scripts into production.

Leave a Comment