No questions found.
Try different keywords.
SELECT MAX(salary) AS SecondHighestSalary
FROM employees
WHERE salary < (
SELECT MAX(salary)
FROM employees
);
SELECT name, COUNT(*) FROM employees GROUP BY name HAVING COUNT(*) > 1;
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;
SELECT * FROM employees WHERE join_date >= CURRENT_DATE - INTERVAL '6 months';
SELECT d.department_name FROM departments d LEFT JOIN employees e ON d.department_id = e.department_id WHERE e.id IS NULL;
SELECT name, department_id, salary,
SUM(salary) OVER (PARTITION BY department_id ORDER BY id) AS running_total
FROM employees;
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;
SELECT name, salary,
RANK() OVER (ORDER BY salary DESC) AS salary_rank
FROM employees;
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;
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);
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY purchase_date DESC) AS rn
FROM sales
) sub
WHERE rn = 1;
SELECT customer_id FROM sales s GROUP BY customer_id HAVING COUNT(DISTINCT category_id) = (SELECT COUNT(DISTINCT category_id) FROM sales);
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;
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;
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.
📺 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.
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.
-
1. Always alias your columns for readability. Raw column names like
MAX(salary)mean nothing to a reviewer scanning a report. Always writeMAX(salary) AS highest_salary. This habit signals that you think like an engineer who writes for others to read, not just for the machine to execute. -
2. Use EXISTS instead of IN for correlated subqueries. When checking membership against a large subquery result set,
EXISTSshort-circuits as soon as it finds the first match, making it significantly faster thanINwhich evaluates the entire subquery. Example:WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id)is preferred overWHERE id IN (SELECT customer_id FROM orders). - 3. Explain your JOIN logic step by step out loud. Interviewers want to hear your reasoning. Before writing the query, verbally state: "I need to combine the employees table with the departments table on the foreign key department_id to get both name and department name in one result set." This narration demonstrates structured thinking even when you are under pressure.
-
4. Use CTEs (WITH clauses) instead of deeply nested subqueries. Nothing signals strong SQL maturity like refactoring a four-level nested subquery into clean, named CTEs. A Common Table Expression like
WITH active_users AS (SELECT * FROM users WHERE status = 'active')dramatically improves readability and is easier to debug step-by-step during an interview walkthrough. -
5. Always specify the columns you SELECT β avoid SELECT *. In interviews and production code alike,
SELECT *is a red flag. It signals lazy coding, can return unintended columns, and creates fragile queries that break when tables are altered. Explicitly list needed columns:SELECT employee_id, full_name, department_id FROM employees. - 6. Understand the execution order of SQL clauses. Many candidates write queries that logically seem right but fail because they misuse WHERE vs HAVING. Remember: SQL executes in this order β FROM β WHERE β GROUP BY β HAVING β SELECT β ORDER BY. HAVING filters after aggregation; WHERE filters before. This is a foundational concept tested at every experience level.
-
7. Validate NULLs explicitly β do not rely on equality checks. A critical QA mindset applies directly to SQL: always think about NULL values in your dataset.
WHERE column = NULLnever returns rows. The correct form isWHERE column IS NULL. Failing to handle NULLs in your queries is one of the most common ways QA engineers introduce data validation defects. -
8. Use window functions to avoid self-joins for ranking tasks. Instead of writing a self-join to find the second highest salary (a common but inefficient approach), demonstrate fluency with
DENSE_RANK() OVER (ORDER BY salary DESC). Modern interviewers at senior levels specifically look for window function usage as proof that you understand performance-conscious query design.
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:
- Always alias your tables and columns. Don't write
SELECT * FROM users u JOIN orders o. WriteSELECT u.first_name, o.order_date FROM users u JOIN orders o. It prevents ambiguity. - Format your code. Put SELECT, FROM, WHERE, and JOIN on separate lines. A beautifully formatted query instantly signals experience.
- Explain your JOIN logic out loud. As you type, say "I'm using a LEFT JOIN here because we need all users, even those who haven't placed an order." This shows you understand the data relationships.
- Use EXISTS instead of IN for large subqueries. If querying a massive table, explain to the interviewer that
EXISTSis generally more performant thanINbecause it stops scanning once a match is found. - Filter early. Put filtering conditions in the
ONclause of a JOIN rather than waiting for theWHEREclause to reduce the dataset size early. - Be careful with GROUP BY. Remember that any column in the SELECT clause that isn't wrapped in an aggregate function (like SUM or COUNT) must be in the GROUP BY clause.
- Use CTEs (WITH clause) over nested subqueries. Common Table Expressions make complex queries read top-to-bottom logically, whereas nested subqueries require reading inside-out.
- Clarify null handling. Ask the interviewer, "Can this column contain NULL values? If so, should I use COALESCE or IS NOT NULL to handle them?"
Common SQL Mistakes in QA Interviews
- 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.
- WHERE vs HAVING confusion: Trying to filter aggregate results using WHERE. Remember: WHERE filters rows before aggregation, HAVING filters groups after aggregation.
- Counting NULLs incorrectly: Assuming
COUNT(column_name)counts all rows. It only counts non-null rows. UseCOUNT(*)to count everything. - Forgetting the wildcards in LIKE: Writing
WHERE name LIKE 'John'instead ofWHERE name LIKE '%John%'. - Cartesian Products: Forgetting the ON condition in a JOIN, resulting in a massive CROSS JOIN that crashes the database (or fails the interview).