Last chance! 50% off DataCamp Premium
Sale ends in
Whether you're a job hunter looking for a new opportunity to apply your SQL skills or a hiring manager who is going to interrogate a candidate for a job opening in their company, knowing common SQL interview questions and answers is a must.
This article lists 99 SQL interview questions and answers for 2026, covering key SQL topics to help you prepare, learn, and hire effectively, including:
For those looking to enhance their knowledge and skills further, consider exploring our comprehensive courses in data engineering, cloud technologies, and AWS.
SQL interviews tend to mirror the way people actually learn the language.
Early on, it's about vocabulary and grammar, like knowing what a join is, how SELECT works, and the difference between DDL and DML.
As you become more familiar, the focus shifts from "can you write a query" to "can you write the right query." You start to understand when an index helps, why normalization matters, and how subtly different commands like DELETE and TRUNCATE behave under the hood.
At the senior end, syntax is assumed, and the real test is problem-solving: handling duplicates, NULLs, ties, and ranking logic with window functions and CTEs, and reasoning about transactions, concurrency, and performance.
Functions in SQL. You should know about aggregate and scalar functions, as well as built-in and user-defined functions.
Advanced commands. Questions may cover topics like joins, primary and foreign keys, indexes, and SQL relationships.
Database design. Expect questions on normalization, denormalization, and the differences between various SQL statements like DELETE, TRUNCATE, and DROP.
Advanced queries. You may be asked about subqueries, both nested and correlated, as well as how to perform specific tasks like finding the nth highest value in a column.
Before asking you technical questions, your interviewer may ask you some general questions about your overall experience with SQL.\
Don't worry if your experience in SQL is limited: this is something your interviewer, most probably, already knows from your resume. Since they are interested in talking to you anyway, your profile was considered a good fit for their company. Also, it's perfectly fine if you have only worked with one SQL dialect. Remember that all SQL dialects are fairly similar. Therefore, being familiar with only one of them is a solid basis for you to learn any others.
It stands for Structured Query Language, and it's a programming language used for interaction with relational database management systems (RDBMS). This includes fetching, updating, inserting, and removing data from tables.
The various versions of SQL, both free and paid, are also called SQL dialects. All the dialects of SQL have a very similar syntax and vary insignificantly only in additional functionality. Some examples are Microsoft SQL Server, PostgreSQL, MySQL, SQLite, T-SQL, and Oracle.
Using SQL, we can:
Your interviewer may get the ball rolling by starting with the easier questions:
Also known as an SQL command. It's a string of characters interpreted by the SQL engine as a legal command and executed accordingly. Some examples of SQL statements are SELECT, CREATE, DELETE, DROP, REVOKE, and so on.
A query is a piece of code written in SQL to access or modify data from a database.
There are two types of SQL queries: queries for data retrieval and data modification. The first ones are used to retrieve the necessary data (this also includes limiting, grouping, ordering the data, extracting the data from multiple tables, etc.), while the second ones are used to create, add, delete, update, and rename the data.
Also called an inner query, a query placed inside another query, or an outer query. A subquery may occur in the clauses such as SELECT, FROM, WHERE, UPDATE, etc. It's also possible to have a subquery inside another subquery. The innermost subquery is run first, and its result is passed to the containing query (or subquery).
A clause used to combine and retrieve records from two or multiple tables. SQL tables can be joined based on the relationship between the columns of those tables. Check out our SQL joins tutorial for more context, plus our dedicated guide to SQL joins interview questions.
A human-readable clarification of what a particular piece of code does. SQL code comments can be single-line (preceded by a double dash --) or span over multiple lines (as follows: /*comment_text*/). When the SQL engine runs, it ignores code comments. The purpose of adding SQL code comments is to make the code more comprehensive for those people who will read it in the future.
A temporary name given to a table (or a column in a table) while executing a certain SQL query. Aliases are used to improve the code readability and make the code more compact. An alias is introduced with the AS keyword:
SELECT col_1 AS column
FROM table_name;
Now, let's move on to the technical SQL interview questions and some potential answers to them.
When answering technical questions, the best strategy is to give as precise answers as possible. It may look like an attempt to deviate from the main topic. In addition, it may provoke additional questions about which you can feel less confident.
All in all, SQL allows querying a database in multiple ways. In addition, SQL easily integrates with other programming languages, such as Python or R, so we can use their combined power.
DDL: CREATE, ALTER TABLE, DROP, TRUNCATE, and ADD COLUMN
DML: UPDATE, DELETE, and INSERT
DCL: GRANT and REVOKE
TCL: COMMIT, SET TRANSACTION, ROLLBACK, and SAVEPOINT
DQL: – SELECT
It stands for Database Management System, a software package used to perform various operations on the data stored in a database, such as accessing, updating, wrangling, inserting, and removing data. There are various types of DBMS, such as relational, hierarchical, network, graph, or object-oriented. These types are based on the way the data is organized, structured, and stored in the system.
It stands for Relational Database Management System. It's the most common type of DBMS used for working with data stored in multiple tables related to each other by means of shared keys. The SQL programming language is designed to interact with RDBMS. Some examples of RDBMS are MySQL, PostgreSQL, Oracle, MariaDB, etc.
A table is an organized set of related data stored in a tabular form, i.e., in rows and columns. A field is another term for a column of a table.
A set of conditions defining the type of data that can be input into each column of a table. Constraints ensure data integrity in a table and block undesired actions.
DEFAULT – provides a default value for a column.
UNIQUE – allows only unique values.
NOT NULL – allows only non-null values.
PRIMARY KEY – allows only unique and strictly non-null values (NOT NULL and UNIQUE).
FOREIGN KEY – provides shared keys between two or more tables.
(INNER) JOIN – returns only those records that satisfy a defined join condition in both (or all) tables. It's a default SQL join.
LEFT (OUTER) JOIN – returns all records from the left table and those records from the right table that satisfy a defined join condition.
RIGHT (OUTER) JOIN – returns all records from the right table and those records from the left table that satisfy a defined join condition.
FULL (OUTER) JOIN – returns all records from both (or all) tables. It can be considered as a combination of left and right joins.
Note: FULL OUTER JOIN is supported by PostgreSQL, SQL Server, Oracle, and MySQL 8.0 and above, but MySQL only allows it through UNION patterns; meanwhile, SQLite does not support RIGHT JOIN, which can be emulated using LEFT JOIN in combination with UNION.
A column (or multiple columns) of a table to which the PRIMARY KEY constraint was imposed to ensure unique and non-null values in that column. In other words, a primary key is a combination of the NOT NULL and UNIQUE constraints.The primary key uniquely identifies each record of the table.
Related concept — Surrogate key: A surrogate key is an artificially generated identifier (typically a sequential integer or UUID) assigned to each record, independent of the actual data values. Unlike natural keys (e.g., an email address), surrogate keys remain stable when business data changes, making them a popular choice for primary keys in production databases.
Each table can define at most one PRIMARY KEY (which may be composite). A PRIMARY KEY is strongly recommended but not strictly required by all engines.
A column (or multiple columns) of a table to which the UNIQUE constraint was imposed to ensure unique values in that column, including a possible NULL value (the only one).
Note:
NULL allowed unless you use a filtered index.NULLs allowed because NULL <> NULL.A column (or multiple columns) of a table to which the FOREIGN KEY (or UNIQUE key) constraint was imposed to link this column to the primary key in another table (or several tables).The purpose of foreign keys is to keep connected various tables of a database.
A special data structure related to a database table and used for storing its important parts and enabling faster data search and retrieval. Indexes are especially efficient for large databases, where they significantly enhance query performance.
A collection of database structural elements such as tables, stored procedures, indexes, functions, and triggers. It shows the overall database architecture, specifies the relationships between various objects of a database, and defines different access permissions for them. Read our database schema guide for a deeper understanding.
A reserved character, a combination of characters, or a keyword used in SQL queries to perform a specific operation. SQL operators are commonly used with the WHERE clause to set a condition (or conditions) for filtering the data.
Arithmetic (+, -, *, /, etc.)
Comparison (>, <, =, >=, etc.)
Compound (+=, -=, *=, /=, etc.)
Logical (AND, OR, NOT, BETWEEN, etc.)
String (%, _, +, ^, etc.)
Set (UNION, UNION ALL, INTERSECT, and MINUS (or EXCEPT))
A condition imposed on a SQL query to filter the data to obtain the desired result. Some examples are WHERE, LIMIT, HAVING, LIKE, AND, OR, ORDER BY, etc.
The most common ones are FROM, GROUP BY, JOIN, WHERE, ORDER BY, LIMIT, and HAVING.
Using theCREATE TABLE statement. For example, to create a table with three columns of predefined datatypes, we apply the following syntax:
CREATE TABLE table_name (col_1 datatype,
col_2 datatype,
col_3 datatype);
Using the UPDATE statement. The syntax is:
UPDATE table_name
SET col_1 = value_1, col_2 = value_2
WHERE condition;
Using the DROP TABLE statement. The syntax is: DROP TABLE table_name;.
Using the COUNT() aggregate function with the asterisk passed as its argument: SELECT COUNT(*) FROM table_name;.
Using the ORDER BY statement:
SELECT * FROM table_name
ORDER BY col_1;
We can specify that we need a descending order using the DESC keyword; otherwise, the order will be ascending by default. Also, we can sort by more than one column and specify for each one, ascending or descending order separately. For example:
SELECT * FROM table_name
ORDER BY col_1 DESC, col_3, col_6 DESC;
Using the asterisk * with the SELECT statement. The syntax is: SELECT * FROM table_name;.
Using the INTERSECT statement:
SELECT col1, col2 FROM table_1
INTERSECT
SELECT col1, col2 FROM table_2;
Note: INTERSECT requires the same number of columns and compatible types.
This statement is used with the SELECT statement to filter out duplicates and return only unique values from a column of a table. The syntax is:
SELECT DISTINCT col_1
FROM table_name;
Relationships are the connections and correlations between entities, basically meaning how two or more tables of a database are related to one another. For example, we can find an ID of the same client in a table on sales data and in a customer table.
A NULL value indicates the absence of data for a certain cell of a table. Instead, zero is a valid numeric value, and an empty string is a legal string of zero length.
SQL databases are relational, structured, and use tables with predefined schemas, while NoSQL databases are non-relational, schema-less, and designed to handle unstructured or semi-structured data.
Challenges include performance tuning for large datasets, managing indexing strategies, ensuring data integrity with constraints, handling concurrent transactions, and optimizing query execution.
A Common Table Expression (CTE) is a temporary named result set that you can reference within a SELECT, INSERT, UPDATE, or DELETE statement. CTEs improve query readability and allow you to break complex queries into simpler, reusable parts. The syntax uses the WITH keyword:
WITH sales_summary AS (
SELECT product_id, SUM(amount) AS total_sales
FROM sales
GROUP BY product_id
)
SELECT p.product_name, s.total_sales
FROM products p
JOIN sales_summary s ON p.id = s.product_id
WHERE s.total_sales > 10000;
CTEs are particularly useful for recursive queries (hierarchical data like org charts) and when you need to reference the same subquery multiple times.
Window functions perform calculations across a set of rows related to the current row, without collapsing the result into a single output row like aggregate functions do. They use the OVER() clause to define the window of rows.
Key window functions include:
ROW_NUMBER() – assigns a unique sequential number to each rowRANK() – assigns a rank with gaps for tiesDENSE_RANK() – assigns a rank without gaps for tiesLAG() / LEAD() – access data from previous/next rowsSUM() OVER(), AVG() OVER() – running or cumulative calculationsExample: Calculate running total of sales
SELECT
order_date,
amount,
SUM(amount) OVER (ORDER BY order_date) AS running_total
FROM orders;
All three are ranking window functions, but they handle ties differently:
ROW_NUMBER() – always assigns unique sequential numbers (1, 2, 3, 4...), even for tiesRANK() – assigns the same rank to ties, then skips numbers (1, 2, 2, 4...)DENSE_RANK() – assigns the same rank to ties, without skipping (1, 2, 2, 3...)SELECT
name,
score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num,
RANK() OVER (ORDER BY score DESC) AS rank,
DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank
FROM students;
Use DENSE_RANK() when finding the "nth highest" value where ties should share the same position.
In this section, we take a look at the most popular intermediate SQL questions and answers so that you'll know what to expect from your interviewer.
A database object representing a set of SQL statements frequently used for a certain task. A function takes in some input parameters, performs calculations or other manipulations on them, and returns the result. Functions help improve code readability and avoid repetition of the same code snippets.
On the other hand, SQL functions can be built-in (defined by the system) or user-defined (created by the user for their specific needs).
AVG() – returns the average value
SUM() – returns the sum of values
MIN() – returns the minimum value
MAX() – returns the maximum value
COUNT() – returns the number of rows, including those with null values
LEN() (in other SQL dialects – LENGTH()) – returns the length of a string, including the blank spaces
UCASE() (in other SQL dialects – UPPER()) – returns a string converted to the upper case
LCASE() (in other SQL dialects – LOWER()) – returns a string converted to the lower case
INITCAP() – returns a string converted to the title case (i.e., each word of the string starts from a capital letter)
MID() (in other SQL dialects – SUBSTR()) – extracts a substring from a string
ROUND() – returns the numerical value rounded to a specified number of decimals
NOW() – returns the current date and time
Case manipulation functions represent a subset of character functions, and they're used to change the case of the text data. With these functions, we can convert the data into the upper, lower, or title case.
UCASE() (in other SQL dialects – UPPER()) – returns a string converted to the upper case
LCASE() (in other SQL dialects – LOWER()) – returns a string converted to the lower case
INITCAP() – returns a string converted to the title case (i.e., each word of the string starts from a capital letter)
Character manipulation functions represent a subset of character functions, and they're used to modify the text data.
CONCAT() – joins two or more string values appending the second string to the end of the first one
SUBSTRING()/SUBSTR() – returns a part of a string satisfying the provided start and end points
LENGTH() (in other SQL dialects – LEN()) – returns the length of a string, including the blank spaces
REPLACE() – replaces all occurrences of a defined substring in a provided string with another substring
INSTR() – returns the numeric position of a defined substring in a provided string
LPAD() and RPAD() – return the padding of the left-side/right-side character for right-justified/left-justified value
TRIM() – removes all the defined characters, as well as white spaces, from the left, right, or both ends of a provided string
Local variables can be accessed only inside the function in which they were declared. Instead, global variables, being declared outside any function, are stored in fixed memory structures and can be used throughout the entire program.
SQL is a standard language for querying and managing relational databases, primarily used for data manipulation and retrieval. PL/SQL (Procedural Language/SQL) is an extension of SQL used in Oracle databases that includes procedural programming constructs like loops, conditions, and exception handling, allowing for complex business logic to be implemented within the database. We have another article on the Top 20 PL/SQL Interview Questions and Answers, which is a good review if you know you will be asked about your knowledge of Oracle.
There is no difference between LEFT JOIN and LEFT OUTER JOIN. They are interchangeable. SQL allows the OUTER keyword to be optional, so LEFT JOIN is simply a shorthand for LEFT OUTER JOIN. Both return all records from the left table and the matching records from the right table.
Indexing creates a special data structure that speeds up data retrieval by allowing the database to find rows more efficiently. It works like an optimized lookup table, reducing the need for full table scans. However, excessive indexing can slow down insert, update, and delete operations due to the need for index maintenance.
A stored procedure is a precompiled set of SQL statements executed as a unit to perform a task. Procedures can modify data or schema objects, manage transactions, and return zero or more result sets. Functions, on the other hand, are typically used in SQL expressions, must return a value (scalar or table-valued), and in many databases are restricted from side effects. Exact behavior differs by DB (e.g., T-SQL has scalar and table-valued functions; PostgreSQL distinguishes between functions and procedures).
Default is ascending (NULLS FIRST/LAST varies by DB). Use ASC/DESC per column keyword as follows:
SELECT * FROM table_name
ORDER BY col_1 DESC;
UNION – returns the records obtained by at least one of two queries (excluding duplicates)
UNION ALL – returns the records obtained by at least one of two queries (including duplicates)
INTERSECT – returns the records obtained by both queries
EXCEPT (called MINUS in MySQL and Oracle) – returns only the records obtained by the first query but not the second one
The LIKE operator in combination with the % and _ wildcards. The % wildcard represents any number of characters including zero, while _ – strictly one character.
While both types of keys ensure unique values in a column of a table, the first one uniquely identifies each record of the table, and the second one prevents duplicates in that column.
The primary key of a table, based on multiple columns.
SELECT – FROM – JOIN – ON – WHERE – GROUP BY – HAVING – ORDER BY – LIMIT
Here is the SQL order of execution:
FROM → ON → JOIN → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT/OFFSET (FETCH)
A virtual table containing a subset of data retrieved from one or more database tables (or other views). Standard views store no data; materialized views do.Views can simplify queries, encapsulate logic, and, combined with privileges, restrict columns/rows. They can join/aggregate data from multiple tables.
Yes. This is also known as nested views. However, we should avoid nesting multiple views since the code becomes difficult to read and debug.
No. Any views based on that table will become invalid after deleting the base table. If we try to use such a view anyway, we'll receive an error message.
In some SQL dialects, such as PostgreSQL, the BOOLEAN data type exists explicitly and takes values TRUE, FALSE, or NULL. In other dialects, such as Microsoft SQL Server, the BIT datatype is used to store Boolean values as integers 1 (true) or 0 (false).
Normalization is a process of database design that includes organizing and restructuring data in a way to reduce data redundancy, dependency, duplication, and inconsistency. This leads to enhanced data integrity, more tables within the database, more efficient data access and security control, and greater query flexibility.
Denormalization is the process opposite of normalization: it introduces data redundancy and combines data from multiple tables. Denormalization optimizes the performance of the database infrastructure in situations when read operations are more important than write operations since it helps avoid complex joins and reduces the time of query running.
Renaming a column means permanently changing its actual name in the original table. Giving an alias to a column means giving it a temporary name while executing an SQL query, with the purpose to make the code more readable and compact.
A correlated subquery is an inner query nested in a bigger (outer) query that refers to the values from the outer query for its execution, meaning that a correlated subquery depends on its outer query.Instead, a non-correlated subquery doesn't rely on the data from the outer query and can be run independently of it.
While a clustered index defines the physical order of records of a table and performs data searching based on the key values, a non-clustered index keeps the order of records that do not match the physical order of the actual data on the disk. A table can have only one clustered index but many non-clustered ones.
The way to implement the if-then-else logic in SQL. This function sequentially checks the provided conditions in the WHEN clauses and returns the value from the corresponding THEN clause when the first condition is satisfied. If none of the conditions is satisfied, the function returns the value from the ELSE clause in case it's provided, otherwise, it returns NULL. The syntax is:
CASE
WHEN condition_1 THEN value_1
WHEN condition_2 THEN value_2
WHEN condition_3 THEN value_3
...
ELSE value
END;
DELETE is a DML (Data Manipulation Language) command used to remove one or more rows from a table based on a condition in the WHERE clause. It is reversible only if wrapped in a transaction (via ROLLBACK).
TRUNCATE is a DDL (Data Definition Language) command that removes all rows from a table by deallocating pages. It is faster but generally irreversible, and cannot be used on tables that are referenced by a foreign key.
DROP deletes a table from the database completely, including the table structure and all the associated constraints, relationships with other tables, and access privileges. TRUNCATE deletes all rows from a table without affecting the table structure and constraints. Both are DDL. DROP removes the table and its metadata; TRUNCATE deletes all rows but keeps the table definition. Performance and transactional behavior depend on the DB engine.
The first one works on aggregated data after they are grouped, while the second one checks each row individually. If both statements are present in a query, they appear in the following order:WHERE – GROUP BY – HAVING. The SQL engine interprets them also in the same order.
Using the INSERT INTO statement in combination with VALUES. The syntax is:
INSERT INTO table_name
VALUES (value_1, value_2, ...);
Using the DELETE statement. The syntax is:
DELETE FROM table_name
WHERE condition;
In this way, we can also delete multiple records if they satisfy the provided condition.
Using the ALTER TABLE statement in combination with ADD. The syntax is:
ALTER TABLE table_name
ADD column_name datatype;
Using the ALTER TABLE statement in combination with RENAME COLUMN ... TO ... The syntax is:
ALTER TABLE table_name
RENAME COLUMN old_column_name TO new_column_name;
Using the ALTER TABLE statement in combination with DROP COLUMN. The syntax is:
ALTER TABLE table_name
DROP COLUMN column_name;
By checking the remainder of the division by 2. In some SQL versions (e.g., PostgreSQL and MySQL), we use the MOD function, in the others (Microsoft SQL Server and SQLite) – the modulo operator (%). To select all even records using MOD:
SELECT * FROM table_name
WHERE MOD(ID_column, 2) = 0;
To select all even records using %:
SELECT * FROM table_name
WHERE ID_column % 2 = 0;
To select all odd records, the syntax is identical in both cases, only that we would use the inequality operator <> instead of =.
Using the DISTINCT statement in combination with SELECT or creating a unique key for that table.
Using the INSERT INTO statement in combination with VALUES. The syntax is:
INSERT INTO table_name
VALUES (value_1, value_2, ...),
(value_3, value_4, ...),
(value_5, value_6, ...),
...;
Using window functions to handle ties correctly:
SELECT column_name
FROM (
SELECT column_name, DENSE_RANK() OVER (ORDER BY column_name DESC) AS rnk
FROM table_name
) t
WHERE rnk = :n;
For the nth row by order (ignoring ties): ORDER BY column_name DESC OFFSET n-1 ROWS FETCH NEXT 1 ROW ONLY.
Using the LIKE operator in combination with the % and _ wildcards. For example, we need to find all surnames in a table that start with "A". The query is:
SELECT * FROM table_name
WHERE surname LIKE 'A_';
Here, we assume that a surname must contain at least two letters. Without this assumption (meaning that a surname can be just A), the query is as follows:
SELECT * FROM table_name
WHERE surname LIKE 'A%';
The simplest method is to use the aggregate function MAX().
SELECT MAX(id) AS highest_id
FROM table_name;
Using ORDER BY with LIMIT or TOP
SELECT id
FROM table_name
ORDER BY id DESC
LIMIT 1;
Using the RAND() function in combination with ORDER BY and LIMIT. In some SQL dialects, such as PostgreSQL, it's called RANDOM(). For example, the following code will return five random rows from a table in MySQL:
SELECT * FROM table_name
ORDER BY RAND()
LIMIT 5;
Scenario-based questions test your ability to solve real-world business problems with SQL. Interviewers use these to assess not just your syntax knowledge, but your problem-solving approach and ability to handle edge cases like duplicates, NULL values, and ties.
Finding duplicates:
SELECT email, COUNT(*) AS duplicate_count
FROM users
GROUP BY email
HAVING COUNT(*) > 1;
Removing duplicates (keeping one record):
WITH duplicates AS (
SELECT id,
ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) AS rn
FROM users
)
DELETE FROM users
WHERE id IN (SELECT id FROM duplicates WHERE rn > 1);
This approach uses a CTE with ROW_NUMBER() to identify duplicates, keeping the record with the lowest ID.
Use the SUM() window function with an ORDER BY clause:
SELECT
transaction_date,
amount,
SUM(amount) OVER (ORDER BY transaction_date) AS running_total
FROM transactions;
For a running total per category (e.g., per customer):
SELECT
customer_id,
transaction_date,
amount,
SUM(amount) OVER (
PARTITION BY customer_id
ORDER BY transaction_date
) AS customer_running_total
FROM transactions;
This is a classic correlated subquery scenario:
SELECT e.name, e.department, e.salary
FROM employees e
WHERE e.salary > (
SELECT AVG(salary)
FROM employees
WHERE department = e.department
);
Alternatively, using a window function:
SELECT name, department, salary
FROM (
SELECT
name,
department,
salary,
AVG(salary) OVER (PARTITION BY department) AS dept_avg
FROM employees
) t
WHERE salary > dept_avg;
Use LEAD() to compare each value with the next:
SELECT
invoice_number,
LEAD(invoice_number) OVER (ORDER BY invoice_number) AS next_invoice,
LEAD(invoice_number) OVER (ORDER BY invoice_number) - invoice_number - 1 AS gap_size
FROM invoices
WHERE LEAD(invoice_number) OVER (ORDER BY invoice_number) - invoice_number > 1;
This identifies where the gap between consecutive invoice numbers is greater than 1.
Use LAG() to compare with the previous row:
WITH monthly_purchases AS (
SELECT
customer_id,
DATE_TRUNC('month', purchase_date) AS purchase_month,
LAG(DATE_TRUNC('month', purchase_date)) OVER (
PARTITION BY customer_id
ORDER BY DATE_TRUNC('month', purchase_date)
) AS prev_month
FROM purchases
GROUP BY customer_id, DATE_TRUNC('month', purchase_date)
)
SELECT DISTINCT customer_id
FROM monthly_purchases
WHERE purchase_month = prev_month + INTERVAL '1 month';
Use conditional aggregation with CASE statements:
SELECT
product_name,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 1 THEN amount ELSE 0 END) AS jan_sales,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 2 THEN amount ELSE 0 END) AS feb_sales,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 3 THEN amount ELSE 0 END) AS mar_sales
FROM sales
GROUP BY product_name;
Some databases (SQL Server, Oracle) have native PIVOT syntax for this operation.
Use DENSE_RANK() with PARTITION BY:
WITH ranked_products AS (
SELECT
category,
product_name,
SUM(sales_amount) AS total_sales,
DENSE_RANK() OVER (
PARTITION BY category
ORDER BY SUM(sales_amount) DESC
) AS sales_rank
FROM sales
GROUP BY category, product_name
)
SELECT category, product_name, total_sales
FROM ranked_products
WHERE sales_rank <= 3
ORDER BY category, sales_rank;
ACID is an acronym for the four key properties that guarantee reliable database transactions:
Example transaction:
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;
A deadlock occurs when two or more transactions are waiting for each other to release locks, creating a circular dependency where neither can proceed.
Example scenario: Transaction A locks Table X and waits for Table Y, while Transaction B locks Table Y and waits for Table X.
Prevention strategies:
Key optimization strategies:
Add appropriate indexes: Create indexes on columns used in WHERE, JOIN, and ORDER BY clauses
Analyze execution plans: Use EXPLAIN (PostgreSQL/MySQL) or EXPLAIN PLAN (Oracle) to identify bottlenecks
Avoid SELECT *: Only retrieve the columns you need
Use JOINs instead of subqueries: JOINs are often more efficient than correlated subqueries
Limit result sets: Use LIMIT/TOP when you don't need all rows
Avoid functions on indexed columns: WHERE YEAR(date_col) = 2026 can't use an index; use WHERE date_col >= '2026-01-01' instead
Consider partitioning: For very large tables, partition by date or category
NULL represents missing or unknown data and requires special handling:
Comparisons: Use IS NULL or IS NOT NULL instead of = NULL
COALESCE(): Returns the first non-NULL value: COALESCE(column, 'default')
NULLIF(): Returns NULL if two values are equal: NULLIF(a, b)
ISNULL() / NVL(): Database-specific functions to replace NULL values
SELECT
name,
COALESCE(phone, email, 'No contact') AS contact_info,
CASE WHEN status IS NULL THEN 'Unknown' ELSE status END AS status
FROM customers;
This is an advanced "islands and gaps" problem:
WITH login_groups AS (
SELECT
user_id,
login_date,
login_date - ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY login_date
) * INTERVAL '1 day' AS group_id
FROM user_logins
)
SELECT
user_id,
MIN(login_date) AS streak_start,
MAX(login_date) AS streak_end,
COUNT(*) AS streak_length
FROM login_groups
GROUP BY user_id, group_id
ORDER BY streak_length DESC
LIMIT 1;
The trick is subtracting a row number from each date – consecutive dates will produce the same "group_id".
While SQL interview preparation is crucial for job seekers and hiring managers, it’s equally important for businesses to invest in continuous SQL training for their teams. Being able to work with data is more important than ever, so ensuring that your employees have strong SQL skills can be a game-changer for your company's success.
If you’re a team leader or business owner looking to ensure your whole team is proficient in SQL, DataCamp for Business offers tailored training programs that can help your employees master SQL skills, from the basics to advanced concepts. We can provide:
Investing in SQL upskilling through platforms like DataCamp not only enhances your team’s capabilities but also provides your business with a strategic advantage, enabling you to stay competitive and deliver results. Talk to one of our team and request a demo today.
To sum up, we discussed the 99 essential beginner, intermediate, and scenario-based SQL interview questions and the right answers to them. Hopefully, this information will help you to get ready for the interview and feel more confident, whether you're looking for a job in SQL or hiring candidates for an intermediate SQL position.
If you feel that you need more training to better prepare for an interview, consider browsing our full list of SQL courses:
Train your team in SQL with DataCamp for Business. Comprehensive training, hands-on projects, and detailed performance metrics for your organization.

To start learning SQL, begin with the basics of database concepts and relational database management systems. DataCamp has many resources to help you get started, such as the Introduction to SQL course, Data Analyst in SQL Career Track and the SQL cheat sheet. Alternatively visit the SQL courses page to browse all resources.
On the DataCamp platform there are many SQL projects to hone your skills, suitable for all levels.
Beginners are often asked to explain basic SQL concepts, such as the difference between SELECT and INSERT statements, the purpose of keys in a database (primary keys and foreign keys), and simple queries to fetch data from a single table using conditions (WHERE clause).
Intermediate practitioners might face questions on more complex SQL concepts such as joins (INNER, LEFT, RIGHT, FULL), subqueries, aggregations and grouping data (GROUP BY), and the use of set operations like UNION, INTERSECT, and EXCEPT. They may also be asked to solve problems that involve optimizing queries for performance.
Preparation for an SQL interview should include:
In a technical SQL interview, you can expect questions that test your knowledge of SQL syntax, database design, query optimization, and problem-solving abilities using SQL. To demonstrate your skills:
While the core syntax of SQL is consistent across different RDBMS, each system (like MySQL, PostgreSQL, SQL Server, Oracle) has its own dialect with unique features and functions. Learning a specific SQL dialect is important if you're targeting roles that use a particular RDBMS. Focus on the dialect most relevant to your career goals or the one most commonly used in your industry. However, having a strong foundation in standard SQL makes it easier to adapt to different dialects as needed.
Yes! If you are currently a university teacher or student, you can use DataCamp Classrooms to get our entire premium catalog for FREE. This includes our SQL tracks and certifications.
You may also take a look at our free SQL Basics cheat sheet.
Focus on these key areas: (1) Joins and subqueries – understand INNER, LEFT, RIGHT, and FULL joins, plus correlated vs non-correlated subqueries; (2) Window functions – ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, and running totals; (3) CTEs (Common Table Expressions) – for readable, maintainable queries; (4) Aggregations and GROUP BY – including HAVING clause usage; (5) Query optimization – indexing strategies and execution plans.
All three are ranking window functions, but they handle ties differently: ROW_NUMBER() assigns unique sequential numbers even for ties (1, 2, 3, 4); RANK() gives the same rank to ties but skips subsequent numbers (1, 2, 2, 4); DENSE_RANK() gives the same rank to ties without skipping (1, 2, 2, 3). Use DENSE_RANK when finding the "nth highest" value where ties should share the same position.
IBM Certified Data Scientist (2020), previously Petroleum Geologist/Geomodeler of oil and gas fields worldwide with 12+ years of international work experience. Proficient in Python, R, and SQL. Areas of expertise: data cleaning, data manipulation, data visualization, data analysis, data modeling, statistics, storytelling, machine learning. Extensive experience in managing data science communities and writing/reviewing articles and tutorials on data science and career topics.
Learn more about SQL with these courses!
Curs
Curs
Curs
articol de blog
Kevin Babitz
14 min.
articol de blog
Kurtis Pykes
15 min.
articol de blog
Laiba Siddiqui
15 min.
articol de blog
Dario Radečić
15 min.
articol de blog
Thalia Barrera
15 min.

articol de blog
Abid Ali Awan
15 min.