A collection of important MySQL interview questions and answers for quick revision and preparation.
MySQL is an open-source relational database management system (RDBMS) that uses SQL (Structured Query Language) to store, manage, and retrieve data. It is widely used due to its performance, scalability, reliability, and ease of integration with applications.
- INNER JOIN: Returns rows with matching values in both tables.
- LEFT (OUTER) JOIN: Returns all rows from the left table and matched rows from the right.
- RIGHT (OUTER) JOIN: Returns all rows from the right table and matched rows from the left.
- FULL OUTER JOIN: Not directly supported in MySQL but can be achieved using
UNION
.
- WHERE: Filters rows before grouping.
- HAVING: Filters groups/aggregates after grouping.
A Primary Key is a column (or set of columns) that uniquely identifies each record in a table.
- Must contain unique values.
- Cannot contain NULL.
- Each table can have only one primary key.
A Foreign Key is a field in one table that refers to the Primary Key in another table. It maintains referential integrity between tables.
- CHAR: Fixed-length storage. Pads with spaces if data is shorter. Faster for fixed-size data.
- VARCHAR: Variable-length storage. Saves only required characters. More memory efficient.
- DELETE: Removes rows based on condition, can be rolled back.
- TRUNCATE: Removes all rows, resets AUTO_INCREMENT, cannot usually be rolled back.
- DROP: Removes the entire table including structure. Permanent.
Indexes are database objects that improve query performance by allowing faster lookups. Best used on columns in WHERE, JOIN, ORDER BY, GROUP BY clauses.
A Transaction is a sequence of operations executed as a single logical unit.
It follows ACID properties:
- Atomicity – All or nothing
- Consistency – Valid state maintained
- Isolation – Independent transactions
- Durability – Changes persist after commit
Normalization is the process of structuring data to remove redundancy and improve integrity.
Common forms: 1NF, 2NF, 3NF, BCNF.
Denormalization combines tables to reduce joins and improve read performance. Increases redundancy intentionally for faster queries.
COUNT()
– Number of rowsSUM()
– Adds valuesAVG()
– Average valueMIN()
– Minimum valueMAX()
– Maximum value
- GROUP BY: Groups rows with identical values, used with aggregate functions.
- ORDER BY: Sorts query results (ascending or descending).
Automatically generates a sequential number for new records (commonly used with Primary Keys).
- UNION: Combines results and removes duplicate rows.
- UNION ALL: Combines results but keeps duplicates.
SELECT CURDATE(); -- Returns current date
SELECT NOW(); -- Returns current date & time
- IN: Checks if a value exists in a given list or subquery result.
- EXISTS: Checks if the subquery returns any rows (more efficient for large datasets).
CREATE TABLE student (
rollNo INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
marks INT
);
- TRIGGER: Automatically invoked on specific table events (INSERT, UPDATE, DELETE).
- STORED PROCEDURE: Reusable code block, executes only when explicitly called.
- Use IS NULL / IS NOT NULL to check.
- IFNULL(expr, default) replaces NULLs with default.
- COALESCE(expr1, expr2, …) returns first non-null value.
A View is a virtual table based on the result of a query.
- Does not store data itself.
- Provides abstraction, simplifies queries, improves security by exposing subsets of data.
This file covers:
- Basic definitions
- Keys (Primary, Foreign)
- Joins, Aggregate functions, Transactions
- Normalization vs Denormalization
- Queries, Indexes, Views, Procedures
A comprehensive list of the Top 50 MySQL SQL Interview Questions & Answers.
This covers basic, intermediate, and advanced queries frequently asked in technical interviews.
SELECT * FROM employees;
SELECT DISTINCT dept_id FROM employees;
SELECT COUNT(*) FROM employees;
SELECT emp_name, salary FROM employees;
SELECT * FROM employees WHERE salary > 50000;
SELECT * FROM employees WHERE join_date > '2022-01-01';
SELECT * FROM employees WHERE emp_name LIKE 'A%';
SELECT * FROM employees WHERE emp_name LIKE '%n';
SELECT * FROM employees ORDER BY salary DESC;
SELECT * FROM employees ORDER BY dept_id, emp_name;
SELECT * FROM employees WHERE manager_id IS NULL;
SELECT emp_name, IFNULL(manager_id, 'N/A') AS manager FROM employees;
SELECT * FROM employees LIMIT 5;
SELECT * FROM employees WHERE salary BETWEEN 40000 AND 70000;
SELECT * FROM employees WHERE dept_id IN (1,2,3);
SELECT SUM(salary) AS total_salary FROM employees;
SELECT AVG(salary) FROM employees;
SELECT MIN(salary) AS min_salary, MAX(salary) AS max_salary FROM employees;
SELECT dept_id, COUNT(*) FROM employees GROUP BY dept_id;
SELECT dept_id, AVG(salary) FROM employees GROUP BY dept_id;
SELECT dept_id, COUNT(*)
FROM employees
GROUP BY dept_id
HAVING COUNT(*) > 5;
SELECT dept_id, SUM(salary)
FROM employees
GROUP BY dept_id;
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id
ORDER BY avg_salary DESC
LIMIT 1;
SELECT emp_name, salary, dept_id
FROM employees e
WHERE salary > (
SELECT AVG(salary) FROM employees WHERE dept_id = e.dept_id
);
SELECT salary, COUNT(*)
FROM employees
GROUP BY salary
HAVING COUNT(*) > 1;
SELECT e.emp_name, d.dept_name
FROM employees e
INNER JOIN departments d ON e.dept_id = d.dept_id;
SELECT e.emp_name, d.dept_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id;
SELECT e.emp_name, d.dept_name
FROM employees e
RIGHT JOIN departments d ON e.dept_id = d.dept_id;
SELECT e.emp_name, d.dept_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id
UNION
SELECT e.emp_name, d.dept_name
FROM employees e
RIGHT JOIN departments d ON e.dept_id = d.dept_id;
SELECT e.emp_name AS Employee, m.emp_name AS Manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.emp_id;
SELECT e.emp_name
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
WHERE d.dept_name = 'Sales';
SELECT e.emp_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id
WHERE d.dept_id IS NULL;
SELECT e.emp_name, d.dept_name, m.emp_name AS Manager
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
LEFT JOIN employees m ON e.manager_id = m.emp_id;
SELECT d.dept_name, MAX(e.salary) AS max_salary
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
GROUP BY d.dept_name;
SELECT d.dept_name
FROM departments d
LEFT JOIN employees e ON d.dept_id = e.dept_id
WHERE e.emp_id IS NULL;
SELECT MAX(salary)
FROM employees
WHERE salary < (SELECT MAX(salary) FROM employees);
SELECT DISTINCT salary
FROM employees e1
WHERE N-1 = (
SELECT COUNT(DISTINCT salary)
FROM employees e2
WHERE e2.salary > e1.salary
);
SELECT emp_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5;
SELECT DISTINCT salary
FROM employees
ORDER BY salary DESC
LIMIT 2,2; -- Skip first two, fetch next two
SELECT emp_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 10 OFFSET 10;
SELECT *
FROM employees
WHERE join_date >= CURDATE() - INTERVAL 30 DAY;
SELECT *
FROM employees
WHERE YEAR(join_date) = YEAR(CURDATE());
UPDATE employees
SET gender = CASE
WHEN gender = 'M' THEN 'F'
WHEN gender = 'F' THEN 'M'
END;
DELETE FROM employees WHERE dept_id IS NULL;
UPDATE employees
SET salary = salary * 1.10
WHERE dept_id = (SELECT dept_id FROM departments WHERE dept_name = 'Sales');
SELECT e1.emp_name, e1.salary, e1.dept_id
FROM employees e1
JOIN employees e2 ON e1.salary = e2.salary
AND e1.dept_id <> e2.dept_id;
SELECT dept_id, COUNT(*) AS total
FROM employees
GROUP BY dept_id
ORDER BY total DESC
LIMIT 1;
SELECT e.emp_name, e.salary, m.emp_name AS Manager, m.salary AS manager_salary
FROM employees e
JOIN employees m ON e.manager_id = m.emp_id
WHERE e.salary > m.salary;
SELECT emp_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 1;
SELECT dept_id, emp_name, salary
FROM employees e
WHERE salary = (
SELECT MIN(salary) FROM employees WHERE dept_id = e.dept_id
);
- Basic Queries: SELECT, WHERE, LIKE, LIMIT (1–15)
- Aggregate Functions: COUNT, AVG, SUM, GROUP BY, HAVING (16–25)
- Joins: INNER, LEFT, RIGHT, SELF JOIN (26–35)
- Advanced: Ranking, Subqueries, Correlated queries, Updates (36–50)