MySQL Coding Interview Questions with Queries
Knowing MySQL theory is important, but during technical interviews you may also be asked to write SQL queries directly.
For PHP, Laravel, backend, and database developer interviews, common SQL coding questions include:
- Finding duplicate records
- Finding highest and second-highest salary
- Finding users without orders
- Working with JOINs
- GROUP BY and HAVING
- Subqueries
- Window functions
- Removing duplicates
- Getting latest records
- Finding Nth highest salary
- Pagination
- Working with dates
- Aggregations
- Real-world order and inventory queries
This article covers practical MySQL coding interview questions with queries and explanations.
Sample Tables Used in This Article
Assume we have the following tables.
employees
id name department_id salary manager_id created_at
departments
id name
users
id name email city status created_at
orders
id user_id total_amount status created_at
products
id name category_id price stock created_at
order_items
id order_id product_id quantity price
Basic MySQL Coding Interview Questions
1. How do you retrieve all records from a table?
SELECT * FROM users;
This returns all rows and all columns from the users table.
In real applications, it is usually better to select only required columns.
SELECT id, name, email FROM users;
2. How do you find all active users?
SELECT * FROM users WHERE status = 1;
The WHERE clause filters rows before they are returned.
3. How do you find users from Bhubaneswar?
SELECT * FROM users WHERE city = 'Bhubaneswar';
4. How do you find users whose name starts with B?
SELECT * FROM users WHERE name LIKE 'B%';
% represents any number of characters.
5. How do you find users whose name contains "ram"?
SELECT * FROM users WHERE name LIKE '%ram%';
Be aware that searches beginning with % may not use normal B-tree indexes efficiently.
6. How do you get the latest 10 users?
SELECT * FROM users ORDER BY created_at DESC LIMIT 10;
7. How do you get the top 5 highest-paid employees?
SELECT * FROM employees ORDER BY salary DESC LIMIT 5;
8. How do you find employees whose salary is between 50,000 and 80,000?
SELECT * FROM employees WHERE salary BETWEEN 50000 AND 80000;
9. How do you find users from multiple cities?
SELECT * FROM users WHERE city IN ( 'Bhubaneswar', 'Cuttack', 'Puri' );
10. How do you find users whose phone number is NULL?
SELECT * FROM users WHERE phone IS NULL;
Do not use:
phone = NULL
NULL must be checked using IS NULL or IS NOT NULL.
Salary-Based Interview Questions
11. How do you find the highest salary?
SELECT MAX(salary) AS highest_salary FROM employees;
12. How do you find the second-highest salary?
One common approach is:
SELECT MAX(salary) AS second_highest_salary FROM employees WHERE salary < ( SELECT MAX(salary) FROM employees );
This returns the second distinct highest salary.
13. How do you find the second-highest salary using ORDER BY?
SELECT DISTINCT salary FROM employees ORDER BY salary DESC LIMIT 1 OFFSET 1;
DISTINCT is important if multiple employees have the same salary.
14. How do you find the third-highest salary?
SELECT DISTINCT salary FROM employees ORDER BY salary DESC LIMIT 1 OFFSET 2;
15. How do you find the Nth highest salary?
With window functions:
SELECT salary FROM ( SELECT salary, DENSE_RANK() OVER ( ORDER BY salary DESC ) AS salary_rank FROM employees ) ranked WHERE salary_rank = 3;
Replace 3 with the required rank.
16. How do you find employees earning more than the average salary?
SELECT * FROM employees WHERE salary > ( SELECT AVG(salary) FROM employees );
17. How do you find employees earning below average salary?
SELECT * FROM employees WHERE salary < ( SELECT AVG(salary) FROM employees );
18. How do you find the highest salary in each department?
SELECT department_id, MAX(salary) AS highest_salary FROM employees GROUP BY department_id;
19. How do you find the employee with the highest salary in each department?
Using a window function:
SELECT * FROM ( SELECT e.*, DENSE_RANK() OVER ( PARTITION BY department_id ORDER BY salary DESC ) AS salary_rank FROM employees e ) ranked WHERE salary_rank = 1;
This also handles multiple employees having the same highest salary.
20. How do you find the second-highest-paid employee in each department?
SELECT * FROM ( SELECT e.*, DENSE_RANK() OVER ( PARTITION BY department_id ORDER BY salary DESC ) AS salary_rank FROM employees e ) ranked WHERE salary_rank = 2;
Duplicate Record Interview Questions
21. How do you find duplicate email addresses?
SELECT email, COUNT(*) AS total FROM users GROUP BY email HAVING COUNT(*) > 1;
The HAVING clause filters grouped results.
22. How do you find duplicate records based on both name and email?
SELECT name, email, COUNT(*) AS total FROM users GROUP BY name, email HAVING COUNT(*) > 1;
23. How do you display all duplicate rows?
SELECT * FROM users WHERE email IN ( SELECT email FROM users GROUP BY email HAVING COUNT(*) > 1 ) ORDER BY email;
24. How would you prevent duplicate emails?
Add a UNIQUE constraint:
ALTER TABLE users ADD CONSTRAINT unique_users_email UNIQUE (email);
This protects data integrity at the database level.
JOIN Interview Questions
25. How do you get users with their orders?
SELECT u.id, u.name, o.id AS order_id, o.total_amount FROM users u INNER JOIN orders o ON u.id = o.user_id;
INNER JOIN returns only users who have matching orders.
26. How do you get all users including those without orders?
SELECT u.id, u.name, o.id AS order_id FROM users u LEFT JOIN orders o ON u.id = o.user_id;
LEFT JOIN preserves every user from the left table.
27. How do you find users who have never placed an order?
SELECT u.* FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.id IS NULL;
This is one of the most common SQL interview queries.
28. How do you find users who have placed at least one order?
Using EXISTS:
SELECT * FROM users u WHERE EXISTS ( SELECT 1 FROM orders o WHERE o.user_id = u.id );
29. How do you get employees with their department names?
SELECT e.id, e.name, e.salary, d.name AS department FROM employees e LEFT JOIN departments d ON e.department_id = d.id;
30. How do you show employees with their manager names?
This requires a self join.
SELECT e.name AS employee, m.name AS manager FROM employees e LEFT JOIN employees m ON e.manager_id = m.id;
GROUP BY and HAVING Questions
31. How do you count employees in each department?
SELECT department_id, COUNT(*) AS total_employees FROM employees GROUP BY department_id;
32. How do you find departments with more than 10 employees?
SELECT department_id, COUNT(*) AS total_employees FROM employees GROUP BY department_id HAVING COUNT(*) > 10;
33. How do you calculate total sales for each customer?
SELECT user_id, SUM(total_amount) AS total_sales FROM orders WHERE status = 'completed' GROUP BY user_id;
34. How do you find users who spent more than 50,000?
SELECT user_id, SUM(total_amount) AS total_spent FROM orders WHERE status = 'completed' GROUP BY user_id HAVING SUM(total_amount) > 50000;
35. How do you calculate average salary by department?
SELECT department_id, AVG(salary) AS average_salary FROM employees GROUP BY department_id;
Subquery Interview Questions
36. How do you find employees belonging to the department with the highest average salary?
SELECT * FROM employees WHERE department_id = ( SELECT department_id FROM employees GROUP BY department_id ORDER BY AVG(salary) DESC LIMIT 1 );
37. How do you find products priced above the average product price?
SELECT * FROM products WHERE price > ( SELECT AVG(price) FROM products );
38. How do you find the highest-value order?
SELECT * FROM orders WHERE total_amount = ( SELECT MAX(total_amount) FROM orders );
This returns all orders tied for the highest amount.
Latest and Earliest Record Questions
39. How do you find the latest order?
SELECT * FROM orders ORDER BY created_at DESC LIMIT 1;
40. How do you find the oldest user?
SELECT * FROM users ORDER BY created_at ASC LIMIT 1;
41. How do you find the latest order for each user?
Using ROW_NUMBER:
SELECT * FROM ( SELECT o.*, ROW_NUMBER() OVER ( PARTITION BY user_id ORDER BY created_at DESC, id DESC ) AS row_num FROM orders o ) ranked WHERE row_num = 1;
42. How do you find each user's first order?
SELECT * FROM ( SELECT o.*, ROW_NUMBER() OVER ( PARTITION BY user_id ORDER BY created_at ASC, id ASC ) AS row_num FROM orders o ) ranked WHERE row_num = 1;
Date-Based Coding Questions
43. How do you find today's orders?
A range query is often preferable:
SELECT * FROM orders WHERE created_at >= CURRENT_DATE() AND created_at < CURRENT_DATE() + INTERVAL 1 DAY;
44. How do you find yesterday's orders?
SELECT * FROM orders WHERE created_at >= CURRENT_DATE() - INTERVAL 1 DAY AND created_at < CURRENT_DATE();
45. How do you find orders from the last 7 days?
SELECT * FROM orders WHERE created_at >= NOW() - INTERVAL 7 DAY;
46. How do you find orders from the current month?
SELECT * FROM orders WHERE created_at >= DATE_FORMAT( CURRENT_DATE(), '%Y-%m-01' ) AND created_at < DATE_FORMAT( CURRENT_DATE() + INTERVAL 1 MONTH, '%Y-%m-01' );
47. How do you calculate monthly sales?
SELECT YEAR(created_at) AS sales_year, MONTH(created_at) AS sales_month, SUM(total_amount) AS total_sales FROM orders WHERE status = 'completed' GROUP BY YEAR(created_at), MONTH(created_at) ORDER BY sales_year, sales_month;
48. How do you calculate daily sales?
SELECT DATE(created_at) AS order_date, SUM(total_amount) AS total_sales FROM orders WHERE status = 'completed' GROUP BY DATE(created_at) ORDER BY order_date;
Product and Order Queries
49. How do you find products that were never ordered?
SELECT p.* FROM products p LEFT JOIN order_items oi ON p.id = oi.product_id WHERE oi.product_id IS NULL;
50. How do you find the most sold product?
SELECT oi.product_id, SUM(oi.quantity) AS total_quantity FROM order_items oi GROUP BY oi.product_id ORDER BY total_quantity DESC LIMIT 1;
To include the product name:
SELECT p.id, p.name, SUM(oi.quantity) AS total_quantity FROM order_items oi JOIN products p ON p.id = oi.product_id GROUP BY p.id, p.name ORDER BY total_quantity DESC LIMIT 1;
51. How do you find the top 5 best-selling products?
SELECT p.id, p.name, SUM(oi.quantity) AS total_sold FROM products p JOIN order_items oi ON p.id = oi.product_id GROUP BY p.id, p.name ORDER BY total_sold DESC LIMIT 5;
52. How do you find products with stock below 10?
SELECT * FROM products WHERE stock < 10 ORDER BY stock ASC;
53. How do you find out-of-stock products?
SELECT * FROM products WHERE stock = 0;
54. How do you calculate the value of current inventory?
SELECT SUM(price * stock) AS inventory_value FROM products;
Window Function Interview Questions
55. What is ROW_NUMBER()?
ROW_NUMBER assigns a unique sequence number to each row.
SELECT id, name, salary, ROW_NUMBER() OVER ( ORDER BY salary DESC ) AS row_number FROM employees;
56. What is RANK()?
RANK gives the same rank to equal values but leaves gaps.
SELECT name, salary, RANK() OVER ( ORDER BY salary DESC ) AS salary_rank FROM employees;
57. What is DENSE_RANK()?
DENSE_RANK gives the same rank to duplicate values but does not leave gaps.
SELECT name, salary, DENSE_RANK() OVER ( ORDER BY salary DESC ) AS salary_rank FROM employees;
58. What is the difference between ROW_NUMBER, RANK and DENSE_RANK?
Suppose salaries are:
100000 100000 90000
ROW_NUMBER:
1 2 3
RANK:
1 1 3
DENSE_RANK:
1 1 2
59. How do you calculate running total sales?
SELECT id, created_at, total_amount, SUM(total_amount) OVER ( ORDER BY created_at, id ) AS running_total FROM orders WHERE status = 'completed';
60. How do you compare an employee's salary with the previous employee?
Using LAG:
SELECT name, salary, LAG(salary) OVER ( ORDER BY salary ) AS previous_salary FROM employees;
Pagination Interview Questions
61. How do you implement basic SQL pagination?
SELECT * FROM users ORDER BY id LIMIT 20 OFFSET 40;
This returns 20 records after skipping 40.
62. Why can OFFSET pagination become slow?
For very large offsets, MySQL may need to scan and skip many rows before returning the requested results.
For example:
SELECT * FROM users ORDER BY id LIMIT 20 OFFSET 500000;
This can become expensive.
63. How do you implement cursor or keyset pagination?
If the last displayed ID was 500000:
SELECT * FROM users WHERE id > 500000 ORDER BY id LIMIT 20;
This can be much more efficient for large datasets.
Update and Delete Coding Questions
64. How do you increase all product prices by 10%?
UPDATE products SET price = price * 1.10;
Always verify the intended rows before running large UPDATE queries.
65. How do you increase salaries by 10% for one department?
UPDATE employees SET salary = salary * 1.10 WHERE department_id = 2;
66. How do you deactivate users who have not logged in for one year?
Assuming there is a last_login_at column:
UPDATE users SET status = 0 WHERE last_login_at < NOW() - INTERVAL 1 YEAR;
67. How do you delete records older than 5 years?
DELETE FROM logs WHERE created_at < NOW() - INTERVAL 5 YEAR;
For very large tables, deleting millions of records in a single transaction can be risky. Production cleanup may need batching.
Real-World MySQL Coding Questions
68. How do you find the total number of orders for each user?
SELECT u.id, u.name, COUNT(o.id) AS total_orders FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id, u.name;
LEFT JOIN also shows users who have zero orders.
69. How do you find customers with more than 5 completed orders?
SELECT user_id, COUNT(*) AS total_orders FROM orders WHERE status = 'completed' GROUP BY user_id HAVING COUNT(*) > 5;
70. How do you find the customer who spent the most money?
SELECT user_id, SUM(total_amount) AS total_spent FROM orders WHERE status = 'completed' GROUP BY user_id ORDER BY total_spent DESC LIMIT 1;
71. How do you find top 10 customers by revenue?
SELECT u.id, u.name, SUM(o.total_amount) AS total_spent FROM users u JOIN orders o ON u.id = o.user_id WHERE o.status = 'completed' GROUP BY u.id, u.name ORDER BY total_spent DESC LIMIT 10;
72. How do you calculate average order value?
SELECT AVG(total_amount) AS average_order_value FROM orders WHERE status = 'completed';
73. How do you find orders whose amount is above average?
SELECT * FROM orders WHERE total_amount > ( SELECT AVG(total_amount) FROM orders );
74. How do you find categories with no products?
SELECT c.* FROM categories c LEFT JOIN products p ON c.id = p.category_id WHERE p.id IS NULL;
75. How do you find products ordered more than 100 times?
SELECT product_id, SUM(quantity) AS total_quantity FROM order_items GROUP BY product_id HAVING SUM(quantity) > 100;
Transaction and Concurrency Coding Questions
76. How would you transfer money between two accounts?
Use a transaction:
START TRANSACTION; UPDATE accounts SET balance = balance - 1000 WHERE id = 1; UPDATE accounts SET balance = balance + 1000 WHERE id = 2; COMMIT;
If an error occurs:
ROLLBACK;
Both operations should succeed together.
77. How would you prevent overselling the last product?
You can lock the product row inside a transaction:
START TRANSACTION; SELECT stock FROM products WHERE id = 10 FOR UPDATE;
After checking that stock is available:
UPDATE products SET stock = stock - 1 WHERE id = 10; COMMIT;
This helps protect against concurrent purchases.
78. How can you decrease stock atomically?
UPDATE products SET stock = stock - 1 WHERE id = 10 AND stock > 0;
Then check the affected row count.
This is often safer than reading the stock first and updating it later without locking.
Index and Performance Coding Questions
79. How do you create an index?
CREATE INDEX idx_users_email ON users(email);
80. How do you create a composite index?
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
This may help queries such as:
SELECT * FROM orders WHERE user_id = 10 AND status = 'completed';
81. How do you check query execution strategy?
EXPLAIN SELECT * FROM orders WHERE user_id = 100;
EXPLAIN helps you understand how MySQL plans to execute the query.
82. How would you improve this query?
SELECT * FROM users WHERE email = 'user@example.com';
If email is frequently searched and should be unique:
ALTER TABLE users ADD UNIQUE INDEX idx_users_email (email);
Also, if only specific fields are required:
SELECT id, name, email FROM users WHERE email = 'user@example.com';
83. Why may this query be less index-friendly?
SELECT * FROM orders WHERE DATE(created_at) = '2026-09-30';
Applying a function to the indexed column can reduce index efficiency.
A range query can be better:
SELECT * FROM orders WHERE created_at >= '2026-09-30 00:00:00' AND created_at < '2026-10-01 00:00:00';
Advanced SQL Coding Questions
84. How do you find employees who earn more than their manager?
SELECT e.name AS employee, e.salary AS employee_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;
85. How do you find employees with the same salary?
SELECT salary, COUNT(*) AS total FROM employees GROUP BY salary HAVING COUNT(*) > 1;
To get full employee details:
SELECT * FROM employees WHERE salary IN ( SELECT salary FROM employees GROUP BY salary HAVING COUNT(*) > 1 );
86. How do you find the department with the most employees?
SELECT department_id, COUNT(*) AS total_employees FROM employees GROUP BY department_id ORDER BY total_employees DESC LIMIT 1;
87. How do you find departments with average salary above 60,000?
SELECT department_id, AVG(salary) AS average_salary FROM employees GROUP BY department_id HAVING AVG(salary) > 60000;
88. How do you find the percentage contribution of each employee's salary to the total salary?
SELECT name, salary, ROUND( salary * 100.0 / SUM(salary) OVER (), 2 ) AS salary_percentage FROM employees;
89. How do you get the previous order amount for every order?
SELECT id, total_amount, LAG(total_amount) OVER ( ORDER BY created_at, id ) AS previous_order_amount FROM orders;
90. How do you get the next order amount?
SELECT id, total_amount, LEAD(total_amount) OVER ( ORDER BY created_at, id ) AS next_order_amount FROM orders;
Common Interview Trap Questions
91. What is wrong with this query?
SELECT * FROM users WHERE phone = NULL;
NULL cannot be compared using =.
Correct:
SELECT * FROM users WHERE phone IS NULL;
92. What is the difference between COUNT(*) and COUNT(column)?
COUNT(*)
counts rows.
COUNT(phone)
counts non-NULL values in the phone column.
93. What is wrong with using WHERE after GROUP BY for aggregate filtering?
This is incorrect:
SELECT user_id, COUNT(*) FROM orders GROUP BY user_id WHERE COUNT(*) > 5;
The aggregate condition should use HAVING:
SELECT user_id, COUNT(*) FROM orders GROUP BY user_id HAVING COUNT(*) > 5;
94. What happens if you omit WHERE in UPDATE?
UPDATE users SET status = 0;
Every row can be updated.
Always verify the condition before executing production UPDATE or DELETE queries.
95. What happens if multiple employees share the highest salary?
This query:
SELECT * FROM employees ORDER BY salary DESC LIMIT 1;
returns only one employee.
If all employees with the highest salary are required:
SELECT * FROM employees WHERE salary = ( SELECT MAX(salary) FROM employees );
Scenario-Based Coding Questions
96. Your users table contains 50 lakh rows. How would you fetch records efficiently?
I would avoid:
SELECT * FROM users;
For a normal listing:
SELECT id, name, email FROM users WHERE status = 1 ORDER BY id LIMIT 50;
I would also check indexes using:
EXPLAIN SELECT id, name, email FROM users WHERE status = 1 ORDER BY id LIMIT 50;
For later pages, keyset pagination may be more efficient.
97. A query suddenly becomes slow after the table grows. What should you check?
I would check:
- EXPLAIN output
- Indexes
- Rows examined
- JOIN conditions
- ORDER BY
- GROUP BY
- Selected columns
- Large OFFSET values
- Data distribution
Never optimize only by guessing.
98. How would you find inactive users with no orders in the last 6 months?
SELECT u.* FROM users u WHERE NOT EXISTS ( SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.created_at >= NOW() - INTERVAL 6 MONTH );
99. How would you find customers who placed orders in every month of a year?
SELECT user_id FROM orders WHERE created_at >= '2026-01-01' AND created_at < '2027-01-01' GROUP BY user_id HAVING COUNT( DISTINCT MONTH(created_at) ) = 12;
100. How would you find the highest sale of each month?
SELECT * FROM ( SELECT o.*, ROW_NUMBER() OVER ( PARTITION BY YEAR(created_at), MONTH(created_at) ORDER BY total_amount DESC ) AS row_num FROM orders o ) ranked WHERE row_num = 1;
Important MySQL Coding Topics to Practice
For SQL coding interviews, make sure you can write queries involving:
- SELECT
- WHERE
- AND / OR
- IN
- BETWEEN
- LIKE
- IS NULL
- ORDER BY
- LIMIT
- OFFSET
- COUNT
- SUM
- AVG
- MIN
- MAX
- GROUP BY
- HAVING
- INNER JOIN
- LEFT JOIN
- SELF JOIN
- Subqueries
- EXISTS
- UNION
- Window functions
- ROW_NUMBER
- RANK
- DENSE_RANK
- LAG
- LEAD
- Transactions
- Indexes
- EXPLAIN
- Pagination
How to Answer SQL Coding Questions in an Interview
When an interviewer gives you a SQL problem, avoid immediately writing a query without understanding the requirement.
A good process is:
Understand the tables ↓ Identify relationships ↓ Understand expected output ↓ Decide JOIN / Subquery / Aggregation ↓ Write the query ↓ Check duplicates ↓ Check NULL values ↓ Consider performance ↓ Explain your solution
For example, if the interviewer asks:
"Find the second-highest salary."
Do not only write:
SELECT DISTINCT salary FROM employees ORDER BY salary DESC LIMIT 1 OFFSET 1;
Also explain why DISTINCT is used.
If two employees have the same highest salary, without DISTINCT, OFFSET 1 may still return the same salary.
That explanation shows that you understand the problem instead of only memorizing a query.
Interview Tip: Always Ask About Duplicate Values
Salary questions are a good example.
If an interviewer asks:
"Find the second-highest salary."
You should clarify whether they mean:
- The second row after sorting, or
- The second distinct highest salary
Most interviews mean the second distinct highest salary.
Understanding such edge cases makes your answer stronger.
Interview Tip: Think About NULL Values
NULL behaves differently from normal values.
For example:
WHERE value = NULL
is incorrect.
Use:
WHERE value IS NULL
Also remember that:
COUNT(column)
does not count NULL values.
But:
COUNT(*)
counts rows.
Interview Tip: Do Not Ignore Performance
For experienced developers, writing a logically correct SQL query may not be enough.
You may also be asked:
"Will this query perform well with 50 lakh records?"
You should be ready to discuss:
- Indexes
- Composite indexes
- EXPLAIN
- Pagination
- Rows examined
- Query selectivity
- Large OFFSET values
- JOIN performance
For example:
SELECT * FROM orders WHERE user_id = 10 AND status = 'completed';
If this query is frequently executed, a suitable composite index might be:
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
But index decisions should always be based on actual query patterns.
Final Thoughts
MySQL coding interviews are about more than memorizing SQL syntax.
You should understand how to convert a business requirement into a correct query and how that query behaves with real data.
Practice queries involving users, employees, departments, products, orders, order items, payments, and inventory because these tables closely resemble real backend projects.
Pay special attention to:
- Joins
- Subqueries
- GROUP BY
- HAVING
- Duplicate records
- Highest salary problems
- Window functions
- Date queries
- Transactions
- Indexes
- Large datasets
Most importantly, during an interview explain why you chose a particular SQL approach instead of simply writing the query.
That is what demonstrates real database understanding and practical experience.
Rate this article
No ratings yet. Be the first.
If this helped you, please leave a rating so the next reader knows.
Discussion
Questions and notes from readers. Comments appear after a short review.
No comments yet. Start the discussion.