Top SQL Interview Questions

Curated & Reviewed by Rammehar Dhiman, Senior QA Automation Engineer

A curated collection of real interview questions asked at PwC, Deloitte, EY, KPMG, Tredence, Persistent Systems, and Accenture.

Practice in Interactive Lab

No questions found.

Try different keywords.

01. Find the second highest salary from the Employee table.
Subqueries
SELECT MAX(salary) AS SecondHighestSalary 
FROM employees 
WHERE salary < ( 
    SELECT MAX(salary) 
    FROM employees 
);
02. Find duplicate records in a table.
GROUP BY / HAVING
SELECT name, COUNT(*) 
FROM employees 
GROUP BY name 
HAVING COUNT(*) > 1;
03. Retrieve employees who earn more than their manager.
Self Join
SELECT e.name AS Employee, e.salary, m.name AS Manager, m.salary AS ManagerSalary 
FROM employees e 
JOIN employees m ON e.manager_id = m.id 
WHERE e.salary > m.salary;
04. Find employees who joined in the last 6 months.
Date Functions
SELECT * 
FROM employees 
WHERE join_date >= CURRENT_DATE - INTERVAL '6 months';
05. Get departments with no employees.
LEFT JOIN / NULL
SELECT d.department_name 
FROM departments d 
LEFT JOIN employees e ON d.department_id = e.department_id 
WHERE e.id IS NULL;
06. Running total of salaries by department.
Window Functions
SELECT name, department_id, salary, 
       SUM(salary) OVER (PARTITION BY department_id ORDER BY id) AS running_total 
FROM employees;
07. Find gaps in a sequence of numbers (missing IDs).
NOT EXISTS
SELECT (id + 1) AS missing_id 
FROM employees e1 
WHERE NOT EXISTS ( 
  SELECT 1 FROM employees e2 WHERE e2.id = e1.id + 1 
) 
ORDER BY missing_id;
08. Rank employees based on salary with ties handled properly.
Window Functions
SELECT name, salary, 
       RANK() OVER (ORDER BY salary DESC) AS salary_rank 
FROM employees;
09. Identify overlapping date ranges for bookings.
Self Join
SELECT b1.booking_id, b2.booking_id 
FROM bookings b1 
JOIN bookings b2 ON b1.booking_id <> b2.booking_id 
WHERE b1.start_date <= b2.end_date 
  AND b1.end_date >= b2.start_date;
10. Find departments with the highest average salary.
CTEs / Aggregation
WITH avg_salaries AS ( 
  SELECT department_id, AVG(salary) AS avg_salary 
  FROM employees 
  GROUP BY department_id 
) 
SELECT * 
FROM avg_salaries 
WHERE avg_salary = (SELECT MAX(avg_salary) FROM avg_salaries);
11. Find the most recent purchase per customer.
ROW_NUMBER()
SELECT * 
FROM ( 
  SELECT *, 
         ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY purchase_date DESC) AS rn 
  FROM sales 
) sub 
WHERE rn = 1;
12. Find customers who made purchases in every category available.
Relational Division
SELECT customer_id 
FROM sales s 
GROUP BY customer_id 
HAVING COUNT(DISTINCT category_id) = (SELECT COUNT(DISTINCT category_id) FROM sales);
13. Calculate the percentage change in sales compared to the previous month.
LAG() Window Function
SELECT product_id, sale_month, total_sales, 
       (total_sales - LAG(total_sales) OVER (PARTITION BY product_id ORDER BY sale_month)) * 100.0 / 
       LAG(total_sales) OVER (PARTITION BY product_id ORDER BY sale_month) AS pct_change 
FROM ( 
  SELECT product_id, DATE_TRUNC('month', sale_date) AS sale_month, SUM(amount) AS total_sales 
  FROM sales 
  GROUP BY product_id, sale_month 
) monthly_sales;
14. Retrieve the last 5 orders for each customer.
ROW_NUMBER()
SELECT * 
FROM ( 
  SELECT o.*, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rn 
  FROM orders o 
) sub 
WHERE rn <= 5;
15. Recursive query to compute the total budget under each manager (including subordinates).
RECURSIVE CTE
WITH RECURSIVE manager_budget AS ( 
  SELECT id, manager_id, budget 
  FROM departments 
 
  UNION ALL 
 
  SELECT d.id, d.manager_id, mb.budget 
  FROM departments d 
  JOIN manager_budget mb ON d.manager_id = mb.id 
) 
SELECT manager_id, SUM(budget) AS total_budget 
FROM manager_budget 
GROUP BY manager_id;

Showing all 15 Real Interview Questions. More updates added regularly to keep the database current.

Expand Your Preparation

We have curated comprehensive manuals, cheatsheets, and comparison articles to help you master SQL and database testing.

Study Materials Hub

View QA learning paths and cheatsheets

Technical Blog

Read QA framework reviews and comparisons

📺 Recommended Video Tutorials

Smart QA Hub

Watch expert-led, practical video tutorials covering Manual Testing, Automation (Selenium & Playwright), API Testing, SQL, Java for Testers, and QA Interview Preparation — all in one channel.

Whether you are a beginner starting your QA career or an experienced tester preparing for a senior SDET role, Smart QA Hub delivers real-world, hands-on demonstrations designed to accelerate your learning.

🎥 Watch on Smart QA Hub →

Mastering SQL for Software Testing Interviews

SQL (Structured Query Language) has become a non-negotiable skill for QA engineers, SDETs, and database testers at every experience level. Even roles that are primarily focused on UI automation frequently require candidates to validate backend data using SQL queries. Understanding how to write, read, and debug SQL statements directly impacts your ability to confirm that data entered through the frontend correctly persists in the database, identify data corruption issues, and validate complex business logic involving multiple related tables.

πŸ”— JOINs — The Core Skill

INNER JOIN returns matching rows from both tables. LEFT JOIN returns all left rows plus matches. RIGHT JOIN is the opposite. FULL OUTER JOIN returns all rows from both. Self JOIN links a table to itself. Understanding when to use each is the most frequently tested SQL concept in QA interviews.

📊 Aggregate Functions

COUNT(), SUM(), AVG(), MAX(), MIN() — these are used in combination with GROUP BY to generate summary reports. A common interview question: "Write a query to find all customers who placed more than 5 orders." This requires COUNT with GROUP BY and HAVING clause.

πŸ” Subqueries & CTEs

Subqueries (nested SELECT statements) allow complex filtering. Common Table Expressions (WITH clause) improve readability. Window functions like ROW_NUMBER(), RANK(), and DENSE_RANK() are increasingly tested at senior QA and SDET interview levels.

Practice writing SQL in our SQL Practice Lab to build the muscle memory needed to write queries confidently in a time-pressured interview environment.

SQL Basics for Testers – Essential Commands

As a QA engineer, you don't need to be a database administrator, but you must master data retrieval. The most essential SQL commands for testers include SELECT, WHERE, GROUP BY, HAVING, and ORDER BY. These commands allow you to verify that data entered through the UI is correctly stored and formatted in the backend database.

Logical Order of SQL Query Execution (How Databases Read Queries)
1 FROM / JOINSpecify source tables & links 2 WHEREFilter individual raw rows 3 GROUP BYPartition rows into groups 4 HAVINGFilter aggregated groups 5 SELECTGenerate result columns 6 DISTINCTRemove duplicate output rows 7 ORDER BYSort final display rows 8 LIMIT / OFFSETTruncate returned rows count

SQL JOIN Types Explained with Examples

Understanding JOINs is critical for API and backend testing. INNER JOIN returns matching records from both tables. LEFT JOIN returns all records from the left table and matched records from the right. Testers frequently use these to validate complex data mappings between user accounts and transaction histories.

Advanced SQL Interview Questions with Answers

Senior QA interviews focus heavily on subqueries, correlated subqueries, and window functions (like ROW_NUMBER and RANK). Interviewers often ask you to find the "nth highest salary" or identify duplicate recordsβ€”tasks that prove you can handle complex database testing scenarios.

SQL Practice Tips for QA Engineers

The best way to master database testing is through hands-on practice. Use our SQL Practice Sandbox to write queries against a live dummy database. Practice finding orphans, checking referential integrity, and validating data migrations.

How to Write Clean SQL in QA Interviews: Expert Tips

After more than 12 years conducting and sitting on both sides of QA technical interviews, I can tell you that writing correct SQL is only half the battle. Interviewers at companies like Accenture, Deloitte, and Persistent Systems are equally evaluating how you write your SQL β€” your logical approach, your readability habits, and your understanding of performance implications. The eight tips below are the exact habits I look for when assessing a candidate's database testing maturity.

Common SQL Mistakes in QA Interviews: Pitfalls and Fixes

Even experienced testers make predictable SQL mistakes under interview pressure. Recognizing these patterns in advance β€” and knowing the corrected approach β€” gives you a significant edge. Here are the five most common pitfalls I see candidates make, along with precise fixes.

❌ Pitfall 1: Using WHERE instead of HAVING after GROUP BY

Wrong: SELECT department_id, COUNT(*) FROM employees GROUP BY department_id WHERE COUNT(*) > 5; β€” This throws a syntax error because WHERE cannot reference aggregate functions. Fix: Replace WHERE with HAVING: GROUP BY department_id HAVING COUNT(*) > 5;

❌ Pitfall 2: Confusing INNER JOIN with LEFT JOIN when nulls matter

When asked to find departments with no employees, candidates often write an INNER JOIN which silently excludes null matches. The correct approach is a LEFT JOIN followed by a WHERE e.id IS NULL condition to capture unmatched parent records.

❌ Pitfall 3: Forgetting to handle ties in ranking queries

Using a simple LIMIT 1 OFFSET 1 to find the second highest salary breaks immediately when two employees share the top salary. Always use DENSE_RANK() which correctly handles ties, or use the MAX/WHERE subquery pattern shown in Question 1 above.

❌ Pitfall 4: Not qualifying column names in multi-table queries

When joining two tables that share a column name (like id or name), always prefix columns with the table alias: e.name, m.name. Unqualified column references in multi-table queries produce ambiguous column errors that are easy to avoid and make you look careless.

❌ Pitfall 5: Writing inefficient correlated subqueries in the SELECT clause

Placing a subquery directly in the SELECT clause (e.g., to fetch a count per row) executes that subquery once per row in the outer query β€” a classic N+1 problem. The fix is to pre-aggregate in a CTE or derived table and then JOIN the result, which processes the aggregation only once regardless of dataset size.

Avoiding these five pitfalls will immediately elevate the quality of your SQL in any interview. Practice writing queries under time pressure in our SQL Practice Lab to build the muscle memory to produce clean, correct SQL on demand.

How to Write Clean SQL in QA Interviews: Expert Tips

Writing a query that works is only step one. During my 12 years of conducting QA technical interviews, the candidates who stand out write SQL that is readable, maintainable, and optimized. Here is my actionable advice for live coding rounds:

Common SQL Mistakes in QA Interviews

  1. Using INNER JOIN instead of LEFT JOIN: Losing data because a record in the primary table doesn't have a matching record in the joined table.
  2. WHERE vs HAVING confusion: Trying to filter aggregate results using WHERE. Remember: WHERE filters rows before aggregation, HAVING filters groups after aggregation.
  3. Counting NULLs incorrectly: Assuming COUNT(column_name) counts all rows. It only counts non-null rows. Use COUNT(*) to count everything.
  4. Forgetting the wildcards in LIKE: Writing WHERE name LIKE 'John' instead of WHERE name LIKE '%John%'.
  5. Cartesian Products: Forgetting the ON condition in a JOIN, resulting in a massive CROSS JOIN that crashes the database (or fails the interview).