This file contains common SQL interview questions and concise answers for entry-level roles such as:
- Application Support Engineer
- IT Support Engineer
- Technical Support Engineer
- MIS Executive
- Reporting Executive
- Operations Support Executive
- Junior Database Support Engineer
The focus is on practical understanding rather than memorizing definitions without knowing how to use them.
Data is a collection of facts or information.
Examples include:
- Employee names
- Ticket statuses
- Transaction amounts
- User account details
- Product prices
A database is an organized collection of related data that can be stored, retrieved, updated, and managed.
DBMS means Database Management System.
It is software used to create, manage, retrieve, and modify databases.
Examples include:
- MySQL
- PostgreSQL
- Microsoft SQL Server
- Oracle Database
- SQLite
SQL means Structured Query Language.
It is used to communicate with relational databases.
SQL can:
- Retrieve data
- Insert records
- Update records
- Delete records
- Create tables
- Manage permissions
- Control transactions
| SQL | MySQL |
|---|---|
| Query language | Database management system |
| Used to communicate with databases | Uses SQL to manage databases |
Defines commands such as SELECT |
Stores and processes data |
| Language | Software |
Quick answer:
SQL is a language. MySQL is database software that uses SQL.
A relational database stores data in tables containing rows and columns.
Tables can be connected using keys and relationships.
A table stores related data using rows and columns.
Example:
| employee_id | employee_name | department |
|---|---|---|
| 101 | Ravi | IT Support |
| 102 | Priya | Finance |
A row represents one complete record.
Example:
101 | Ravi | IT Support
A row is also called a record or tuple.
A column represents one type of information.
Examples:
employee_idemployee_namedepartmentsalary
A column may also be called a field or attribute.
A schema defines the structure of a database.
It includes:
- Tables
- Columns
- Data types
- Relationships
- Keys
- Constraints
A data type defines what kind of value a column can store.
Examples:
| Data type | Purpose |
|---|---|
INT |
Whole numbers |
DECIMAL |
Decimal numbers |
VARCHAR |
Variable-length text |
DATE |
Date values |
DATETIME |
Date and time |
BOOLEAN |
True or false |
TEXT |
Long text |
NULL means a value is missing, unknown, or unavailable.
It is not the same as:
- Zero
- Empty text
- Space
- False
| Category | Purpose | Common commands |
|---|---|---|
| DQL | Retrieve data | SELECT |
| DDL | Define database structures | CREATE, ALTER, DROP, TRUNCATE |
| DML | Modify records | INSERT, UPDATE, DELETE |
| DCL | Manage permissions | GRANT, REVOKE |
| TCL | Manage transactions | COMMIT, ROLLBACK, SAVEPOINT |
DDL means Data Definition Language.
It is used to create or modify database structures.
Examples:
CREATE
ALTER
DROP
TRUNCATEDML means Data Manipulation Language.
It is used to insert, update, and delete records.
Examples:
INSERT
UPDATE
DELETEDQL means Data Query Language.
It is used to retrieve data.
SELECTCRUD represents four basic database operations.
| Letter | Operation | SQL command |
|---|---|---|
| C | Create | INSERT |
| R | Read | SELECT |
| U | Update | UPDATE |
| D | Delete | DELETE |
SELECT retrieves data from a table.
SELECT employee_name
FROM employees;Separate column names with commas.
SELECT
employee_name,
department,
salary
FROM employees;SELECT * retrieves every column from a table.
SELECT *
FROM employees;It should be used carefully because it may return unnecessary or sensitive columns.
It may:
- Retrieve unnecessary data
- Reduce readability
- Expose sensitive columns
- Increase data transfer
- Create problems when table structures change
Better:
SELECT
employee_id,
employee_name,
status
FROM employees;DISTINCT removes duplicate result rows.
SELECT DISTINCT department
FROM employees;An alias is a temporary name given to a column or table.
Column alias:
SELECT employee_name AS name
FROM employees;Table alias:
SELECT e.employee_name
FROM employees AS e;Aliases do not permanently rename database objects.
WHERE filters rows based on a condition.
SELECT employee_name
FROM employees
WHERE status = 'Active';| Operator | Meaning |
|---|---|
= |
Equal |
<> |
Not equal |
!= |
Not equal |
> |
Greater than |
< |
Less than |
>= |
Greater than or equal |
<= |
Less than or equal |
AND requires every condition to be true.
SELECT *
FROM employees
WHERE department = 'IT Support'
AND status = 'Active';OR requires at least one condition to be true.
SELECT *
FROM employees
WHERE city = 'Chennai'
OR city = 'Vellore';SQL evaluates AND before OR.
Parentheses make the intended logic clear.
SELECT *
FROM employees
WHERE status = 'Active'
AND (
city = 'Chennai'
OR city = 'Vellore'
);IN checks whether a value matches any value in a list.
SELECT *
FROM employees
WHERE city IN ('Chennai', 'Vellore');BETWEEN checks whether a value falls inside an inclusive range.
SELECT *
FROM employees
WHERE salary BETWEEN 25000 AND 35000;Both boundary values are included.
LIKE performs pattern matching.
SELECT employee_name
FROM employees
WHERE employee_name LIKE 'R%';Wildcards:
| Wildcard | Meaning |
|---|---|
% |
Zero or more characters |
_ |
Exactly one character |
SELECT *
FROM tickets
WHERE issue LIKE '%password%';Use IS NULL.
SELECT *
FROM employees
WHERE phone_number IS NULL;Do not use:
WHERE phone_number = NULL;IS NULL finds missing values.
WHERE email IS NULLIS NOT NULL finds available values.
WHERE email IS NOT NULLORDER BY sorts query results.
SELECT employee_name, salary
FROM employees
ORDER BY salary DESC;| Keyword | Meaning |
|---|---|
ASC |
Ascending |
DESC |
Descending |
Examples:
ASC numbers: lowest to highest
DESC numbers: highest to lowest
ASC dates: oldest to newest
DESC dates: newest to oldest
The default order is usually ascending.
These are generally equivalent:
ORDER BY employee_name;ORDER BY employee_name ASC;LIMIT restricts the number of rows returned.
SELECT employee_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 3;Without ORDER BY, the database does not guarantee which rows will be returned.
Weak:
SELECT *
FROM employees
LIMIT 3;Meaningful:
SELECT *
FROM employees
ORDER BY joining_date DESC
LIMIT 3;OFFSET skips rows before returning results.
SELECT *
FROM tickets
ORDER BY ticket_id
LIMIT 10
OFFSET 20;This skips the first 20 rows and returns the next 10.
An aggregate function summarizes several rows and returns one result.
Common aggregate functions:
COUNT()SUM()AVG()MIN()MAX()
COUNT(*) counts every row.
SELECT COUNT(*) AS employee_count
FROM employees;COUNT(*) counts all rows.
COUNT(column) counts only non-NULL values in that column.
SELECT
COUNT(*) AS total_users,
COUNT(email) AS users_with_email
FROM application_users;It counts unique non-NULL values.
SELECT COUNT(DISTINCT department)
FROM employees;SUM() calculates the total of a numeric column.
SELECT SUM(salary) AS total_salary
FROM employees;AVG() calculates the average of a numeric column.
SELECT ROUND(AVG(salary), 2) AS average_salary
FROM employees;MIN() returns the lowest value.
MAX() returns the highest value.
SELECT
MIN(salary) AS lowest_salary,
MAX(salary) AS highest_salary
FROM employees;Most aggregate functions ignore NULL.
COUNT(*) still counts the row.
AVG(column) does not treat NULL as zero.
No.
SELECT MAX(salary)
FROM employees;returns only the highest salary value.
To retrieve the employee record:
SELECT
employee_name,
salary
FROM employees
ORDER BY salary DESC
LIMIT 1;GROUP BY combines rows with matching values and calculates one result for each group.
SELECT
department,
COUNT(*) AS employee_count
FROM employees
GROUP BY department;SELECT
department,
ROUND(AVG(salary), 2) AS average_salary
FROM employees
GROUP BY department;HAVING filters grouped results.
SELECT
department,
COUNT(*) AS employee_count
FROM employees
GROUP BY department
HAVING COUNT(*) >= 5;| WHERE | HAVING |
|---|---|
| Filters individual rows | Filters grouped results |
| Runs before grouping | Runs after grouping |
| Used with normal conditions | Commonly used with aggregate conditions |
Example:
SELECT
department,
COUNT(*) AS active_employee_count
FROM employees
WHERE status = 'Active'
GROUP BY department
HAVING COUNT(*) >= 2;Normally, no.
Wrong:
WHERE COUNT(*) > 5Correct:
HAVING COUNT(*) > 5The query may fail or produce unreliable results because the database does not know which value should represent the group.
Problematic:
SELECT
employee_name,
department,
COUNT(*)
FROM employees
GROUP BY department;Correct:
SELECT
department,
COUNT(*) AS employee_count
FROM employees
GROUP BY department;A join combines related rows from two or more tables.
INNER JOIN returns only matching rows from both tables.
SELECT
e.employee_name,
d.department_name
FROM employees AS e
INNER JOIN departments AS d
ON e.department_id = d.department_id;LEFT JOIN returns:
- Every row from the left table
- Matching rows from the right table
NULLwhen no right-side match exists
SELECT
e.employee_name,
d.department_name
FROM employees AS e
LEFT JOIN departments AS d
ON e.department_id = d.department_id;INNER JOIN removes unmatched records.
LEFT JOIN preserves every record from the left table.
Use LEFT JOIN with IS NULL.
SELECT
e.employee_id,
e.employee_name
FROM employees AS e
LEFT JOIN departments AS d
ON e.department_id = d.department_id
WHERE d.department_id IS NULL;A self join connects a table to itself.
Example: employees and their managers.
SELECT
e.employee_name AS employee,
m.employee_name AS manager
FROM employees AS e
LEFT JOIN employees AS m
ON e.manager_id = m.employee_id;A CROSS JOIN returns every possible combination of rows from two tables.
If one table has 5 rows and another has 4 rows:
5 × 4 = 20 result rows
MySQL does not directly support FULL OUTER JOIN.
It can be simulated using:
LEFT JOINRIGHT JOINUNION
The query may create a Cartesian product and return every possible row combination.
This can produce an extremely large and incorrect result.
One row may match several rows in another table.
Example:
One ticket can have many comments.
The ticket appears once for every matching comment.
This may be correct behaviour, not a duplicate-data error.
A left join preserves one result row even when no match exists.
Use a right-table key:
COUNT(t.ticket_id)instead of:
COUNT(*)when counting matching records.
A subquery is a query written inside another query.
SELECT
employee_name,
salary
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);A scalar subquery returns exactly one value.
Example:
SELECT MAX(salary)
FROM employees;A correlated subquery refers to the current row from the outer query.
SELECT
e.employee_name,
e.salary
FROM employees AS e
WHERE e.salary > (
SELECT AVG(e2.salary)
FROM employees AS e2
WHERE e2.department_id = e.department_id
);It may run once for each outer row.
A normal subquery runs independently.
A correlated subquery depends on a value from the outer query.
EXISTS checks whether a subquery returns at least one row.
SELECT
d.department_name
FROM departments AS d
WHERE EXISTS (
SELECT 1
FROM employees AS e
WHERE e.department_id = d.department_id
);NOT EXISTS checks whether no matching row exists.
SELECT
d.department_name
FROM departments AS d
WHERE NOT EXISTS (
SELECT 1
FROM employees AS e
WHERE e.department_id = d.department_id
);If the subquery returns NULL, NOT IN may produce unexpected results.
NOT EXISTS is often safer when NULL values are possible.
IN compares a value against a returned list.
EXISTS checks whether matching rows exist.
A join is often clearer when:
- Columns from several tables must be displayed
- Several related tables are involved
- Relationships are the main part of the query
A subquery is often clearer when:
- One calculated value is required
- Existence must be checked
- The outer query depends on a separate summary
INSERT INTO employees (
employee_id,
employee_name,
department,
salary
)
VALUES (
101,
'Ravi',
'IT Support',
28000
);It:
- Improves readability
- Prevents column-order mistakes
- Makes the query safer when table structures change
INSERT INTO employees (
employee_id,
employee_name
)
VALUES
(101, 'Ravi'),
(102, 'Priya'),
(103, 'Arun');UPDATE employees
SET salary = 30000
WHERE employee_id = 101;Every row may be updated.
UPDATE employees
SET status = 'Inactive';This changes the status of every employee.
DELETE FROM employees
WHERE employee_id = 101;Every record is deleted.
The table structure remains.
| Command | Result |
|---|---|
DELETE |
Removes selected or all rows and keeps the table |
TRUNCATE |
Removes all rows and keeps the table |
DROP |
Removes the table itself |
Use this workflow:
1. Run the condition using SELECT.
2. Check the matching records.
3. Start a transaction.
4. Run UPDATE or DELETE.
5. Verify the result.
6. Commit or roll back.
A transaction is a group of database operations treated as one unit.
The changes should either:
- Complete successfully
- Or be cancelled together
COMMIT permanently saves transaction changes.
COMMIT;ROLLBACK cancels uncommitted transaction changes.
ROLLBACK;A savepoint creates a checkpoint inside a transaction.
SAVEPOINT before_delete;Rollback to the checkpoint:
ROLLBACK TO before_delete;An upsert inserts a new record or updates an existing record when a key conflict occurs.
MySQL example:
INSERT INTO application_users (
user_id,
username,
account_status
)
VALUES (
101,
'ravi.k',
'Active'
)
ON DUPLICATE KEY UPDATE
account_status = 'Active';A primary key uniquely identifies each row.
It:
- Must be unique
- Cannot contain
NULL - Should remain stable
A foreign key connects one table to another.
FOREIGN KEY (department_id)
REFERENCES departments(department_id)A composite key contains two or more columns.
PRIMARY KEY (student_id, course_id)A candidate key is a minimal column or column combination that uniquely identifies a row.
An alternate key is a candidate key that was not selected as the primary key.
A surrogate key is an artificial identifier generated for database use.
Example:
user_id INT AUTO_INCREMENT PRIMARY KEYA natural key comes from real-world data.
Examples:
- Email address
- Passport number
- Employee code
- Product serial number
Referential integrity ensures that foreign-key values refer to valid parent records.
It prevents records from pointing to nonexistent related records.
It automatically deletes related child records when the parent record is deleted.
Use it carefully because one deletion may remove many related records.
It changes the child foreign-key value to NULL when the parent is deleted.
The foreign-key column must allow NULL.
A constraint is a rule applied to database data.
Common constraints:
PRIMARY KEYFOREIGN KEYUNIQUENOT NULLDEFAULTCHECK
| Primary key | Unique key |
|---|---|
| Main row identifier | Prevents duplicate values |
Cannot contain NULL |
NULL behaviour depends on DBMS |
| One primary-key constraint per table | Several unique constraints can exist |
Normalization organizes database tables to reduce duplication and improve data consistency.
It helps prevent:
- Duplicate data
- Inconsistent values
- Update problems
- Insertion problems
- Accidental information loss
An insertion anomaly occurs when one fact cannot be stored without another unrelated fact.
Example:
A department cannot be added until an employee joins it.
An update anomaly occurs when repeated data must be updated in several rows.
If one row is missed, the database becomes inconsistent.
A deletion anomaly occurs when deleting one record unintentionally removes other useful information.
First normal form requires:
- One value per cell
- No repeating groups
- Atomic values
- Identifiable rows
Quick recall:
1NF = one value per cell.
Second normal form requires:
- First normal form
- No partial dependency on part of a composite key
Quick recall:
2NF = no partial dependency.
Third normal form requires:
- Second normal form
- No transitive dependency between non-key columns
Quick recall:
3NF = non-key columns depend only on the key.
Denormalization intentionally adds controlled duplication to improve read performance or simplify reporting.
It should be used only when there is a measured requirement.
SELECT
ticket_id,
issue,
priority,
created_at
FROM tickets
WHERE status = 'Open';SELECT
ticket_id,
issue,
priority
FROM tickets
WHERE assigned_to IS NULL;SELECT
ticket_id,
issue,
created_at
FROM tickets
WHERE status <> 'Closed'
ORDER BY created_at ASC
LIMIT 1;SELECT
status,
COUNT(*) AS ticket_count
FROM tickets
GROUP BY status;SELECT
tech.technician_name,
COUNT(t.ticket_id) AS ticket_count
FROM technicians AS tech
LEFT JOIN tickets AS t
ON tech.technician_id = t.assigned_to
GROUP BY
tech.technician_id,
tech.technician_name;SELECT
tech.technician_id,
tech.technician_name
FROM technicians AS tech
LEFT JOIN tickets AS t
ON tech.technician_id = t.assigned_to
WHERE t.ticket_id IS NULL;SELECT
user_id,
username,
failed_login_count
FROM application_users
WHERE account_status = 'Locked';SELECT
user_id,
COUNT(*) AS failed_login_count
FROM login_attempts
WHERE login_status = 'Failed'
GROUP BY user_id
HAVING COUNT(*) >= 3;SELECT
user_id,
username
FROM application_users
WHERE email IS NULL;SELECT
ROUND(AVG(resolution_minutes), 2)
AS average_resolution_minutes
FROM tickets
WHERE status = 'Closed';SELECT
ticket_id,
issue,
closed_at
FROM tickets
WHERE status = 'Closed'
AND resolution_minutes IS NULL;SELECT
t.ticket_id,
t.issue
FROM tickets AS t
LEFT JOIN ticket_comments AS c
ON t.ticket_id = c.ticket_id
WHERE c.comment_id IS NULL;First verify:
SELECT
user_id,
username,
account_status,
failed_login_count
FROM application_users
WHERE user_id = 501;Then update using a transaction:
START TRANSACTION;
UPDATE application_users
SET
account_status = 'Active',
failed_login_count = 0
WHERE user_id = 501
AND account_status = 'Locked';
SELECT
user_id,
username,
account_status,
failed_login_count
FROM application_users
WHERE user_id = 501;
COMMIT;Use ROLLBACK instead of COMMIT if the result is incorrect.
No.
NULL means unknown or missing.
Zero is a known numeric value.
No.
NULL = missing value
'' = known empty text value
No.
Wrong:
WHERE email = NULLCorrect:
WHERE email IS NULLYes.
WHERE salary BETWEEN 25000 AND 30000includes both 25000 and 30000.
No.
Always use ORDER BY when result order matters.
No.
With multiple columns, DISTINCT checks the complete column combination.
SELECT DISTINCT department, status
FROM employees;Normally, no.
The WHERE clause is evaluated before the SELECT alias is created.
Wrong:
SELECT salary * 12 AS annual_salary
FROM employees
WHERE annual_salary > 300000;Correct:
SELECT salary * 12 AS annual_salary
FROM employees
WHERE salary * 12 > 300000;Yes, in most database systems.
SELECT
salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;No.
Only matching rows are returned.
Yes.
Right-side columns become NULL when no match exists.
No.
DISTINCT may hide repeated rows without fixing the underlying join condition.
Correct the relationship first.
No.
It counts only non-NULL values.
No.
AVG() ignores NULL.
No.
Ticket volume must be considered with:
- Ticket complexity
- Priority
- Shift duration
- Assignment method
- Resolution quality
- Escalations
- Waiting time
SQL produces numbers. It does not automatically produce intelligent conclusions, a limitation shared with many dashboards.
SELECT = choose columns
FROM = choose table
WHERE = filter rows
GROUP BY = create groups
HAVING = filter groups
ORDER BY = sort results
LIMIT = restrict rows
INSERT = add records
UPDATE = modify records
DELETE = remove records
COUNT = count
SUM = total
AVG = average
MIN = lowest
MAX = highest
INNER JOIN = matching rows
LEFT JOIN = all left rows
RIGHT JOIN = all right rows
CROSS JOIN = every combination
PRIMARY KEY = identify a row
FOREIGN KEY = connect tables
UNIQUE = prevent duplicates
NOT NULL = require a value
COMMIT = save transaction
ROLLBACK = cancel transaction
Before finalizing a query, check:
- Are the correct tables being used?
- Are the selected columns necessary?
- Are join conditions correct?
- Are text values inside single quotation marks?
- Are
NULLvalues handled correctly? - Are date boundaries correct?
- Is
WHEREfiltering the intended rows? - Is
HAVINGused only for grouped conditions? - Is
ORDER BYincluded when order matters? - Is
LIMITused with meaningful sorting? - Are duplicate rows expected or caused by a bad join?
- Has an
UPDATEorDELETEcondition been tested withSELECT? - Does the affected-row count match the expectation?
- Is the result supported by business context?