Data AnalyticsSql For Analystsintermediate
Updated:

Data Analytics SQL for Analysts Interview Questions and Answers

6 min read

The SQL questions data analysts actually get in interviews — joins, aggregation, window functions and the classic second-highest-salary problem — with correct, tested queries.

TL;DR – Quick Answer

SQL is the most-tested skill in any data analyst interview. Expect questions on the join types, WHERE versus HAVING, GROUP BY aggregation, window functions like ROW_NUMBER and RANK, the second-highest-value pattern, deduplication, and reading a query for correctness and performance. Interviewers grade whether your query returns the right rows and whether you understand execution order, not just syntax.

On This Page

SQL is the skill an analyst is most likely to be tested on live, in front of the interviewer, against a sample schema. The questions are remarkably consistent across companies: a couple of join questions, aggregation with GROUP BY and HAVING, at least one window-function problem, and a pattern classic like the second-highest salary. This page walks those questions with correct, runnable SQL and the reasoning interviewers listen for.

How to answer SQL questions

Talk through which rows the query produces before you optimize anything. Say the logical execution order — FROM and JOIN, then WHERE, then GROUP BY, then HAVING, then SELECT, then ORDER BY — because most SQL bugs come from misunderstanding that order, not from a typo.

Q1. Explain the join types with an example.

An INNER JOIN returns only rows with a match in both tables. A LEFT JOIN returns all rows from the left table plus matches from the right, with NULLs where there is no match. RIGHT JOIN is the mirror image, and FULL OUTER JOIN keeps unmatched rows from both sides.

The interview-favorite use of LEFT JOIN is finding rows with no match — customers who never ordered — by joining and filtering for NULL on the right side.

SELECT c.customer_id, c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
WHERE o.customer_id IS NULL;   -- customers with zero orders

Interview note: Trap: "put the orders filter in WHERE and it still works?" If you filter o.status = 'shipped' in WHERE on a LEFT JOIN, you silently turn it into an INNER JOIN. Put such conditions in the ON clause.

Q2. What is the difference between WHERE and HAVING?

WHERE filters rows before aggregation; HAVING filters groups after aggregation. Aggregate functions like COUNT and SUM are allowed in HAVING but not in WHERE.

To list customers with more than five orders, the count only exists after grouping, so it must live in HAVING. Filtering by a raw column (say a date range) should go in WHERE so fewer rows enter the grouping — that is both correct and faster.

SELECT customer_id, COUNT(*) AS order_count
FROM orders
WHERE order_date >= '2026-01-01'   -- row filter, before grouping
GROUP BY customer_id
HAVING COUNT(*) > 5;               -- group filter, after aggregation

Interview note: Follow-up: "can you use a column alias in HAVING?" It depends on the database; standard SQL evaluates HAVING before SELECT aliases exist, so repeating the aggregate is the portable choice.

Q3. Find the second-highest salary.

The cleanest modern answer uses DENSE_RANK to rank salaries and select rank 2, which correctly handles ties. A subquery with MAX also works but breaks when there are duplicate top salaries.

SELECT DISTINCT salary
FROM (
  SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
  FROM employees
) ranked
WHERE rnk = 2;

The subquery alternative — SELECT MAX(salary) FROM employees WHERE salary < (SELECT MAX(salary) FROM employees) — is fine, but the interviewer usually asks about ties. DENSE_RANK gives the second-highest distinct salary even if several employees share the top value.

Interview note: Trap: "use RANK instead of DENSE_RANK?" RANK skips numbers after ties (1,1,3), so if two people tie for first, RANK never returns 2. DENSE_RANK (1,1,2) is safer for the Nth-value pattern.

Q4. What are window functions, and how are they different from GROUP BY?

A window function computes a value across a set of rows related to the current row, but unlike GROUP BY it does not collapse those rows — every original row is preserved. This makes it ideal for rankings, running totals and comparisons to a group value.

The killer example is showing each employee's salary alongside their department average without losing the individual rows:

SELECT name, department, salary,
       AVG(salary) OVER (PARTITION BY department) AS dept_avg
FROM employees;

A GROUP BY would return one row per department; the window function keeps all employees and attaches the department average to each.

Interview note: Follow-up: "what is the difference between PARTITION BY and GROUP BY?" PARTITION BY defines the window without collapsing rows; GROUP BY collapses each group into a single output row.

Q5. How do you find and remove duplicate rows?

Use ROW_NUMBER partitioned by the columns that define a duplicate, ordered by a tiebreaker, then keep row number 1. Rows numbered greater than 1 are the duplicates to remove.

WITH ranked AS (
  SELECT id,
         ROW_NUMBER() OVER (
           PARTITION BY email ORDER BY created_at
         ) AS rn
  FROM users
)
DELETE FROM users
WHERE id IN (SELECT id FROM ranked WHERE rn > 1);

This keeps the earliest record per email and deletes later duplicates. Interviewers like this because it shows you can both detect duplicates (GROUP BY email HAVING COUNT(*) > 1) and resolve them deterministically.

Interview note: Trap: "just use DISTINCT?" DISTINCT removes fully identical rows in a SELECT but cannot delete duplicates in place or keep a chosen survivor when only some columns match.

Q6. What is the difference between UNION and UNION ALL?

UNION combines two result sets and removes duplicate rows, which requires a sort or hash step. UNION ALL concatenates them and keeps duplicates, so it is faster. Use UNION ALL unless you specifically need deduplication.

Choosing UNION ALL when you know the sets are disjoint is a small performance signal interviewers notice — an unnecessary UNION pays for a dedup that changes nothing.

Interview note: Follow-up: "do the queries need matching columns?" Yes — same number of columns and compatible types, in the same order.

Q7. How do NULLs behave in SQL, and what surprises people?

NULL means unknown, so comparisons with NULL return unknown, not true. x = NULL is never true; you must use IS NULL. Aggregates like COUNT(column) skip NULLs, and NULLs also drop out of most WHERE conditions.

The classic gotcha: WHERE status != 'active' silently excludes rows where status is NULL, because NULL != 'active' is unknown, not true. Wrapping with OR status IS NULL fixes it. This kind of NULL awareness is exactly what an analyst is trusted to get right.

Interview note: Trap: "COUNT() vs COUNT(column)?" COUNT() counts rows including NULLs; COUNT(column) counts only non-NULL values in that column.

Q8. Write a running total of daily revenue.

Use SUM as a window function ordered by date. The frame runs from the first row to the current row, producing a cumulative total.

SELECT order_date,
       daily_revenue,
       SUM(daily_revenue) OVER (
         ORDER BY order_date
         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
       ) AS running_total
FROM daily_sales
ORDER BY order_date;

Running totals, moving averages and period-over-period changes (using LAG) are staple analyst tasks, and reaching for a window function rather than a correlated subquery is the fluent answer.

Interview note: Follow-up: "how would you show month-over-month growth?" Use LAG(revenue) OVER (ORDER BY month) and compute the difference or ratio against the current row.

Q9. How do you approach a slow query?

Look at the execution plan first, confirm the filtered and joined columns are indexed, avoid functions on indexed columns in WHERE (which prevent index use), select only needed columns, and reduce rows early with selective WHERE clauses before joins and aggregation.

For an analyst, the most common self-inflicted slowdown is WHERE YEAR(order_date) = 2026, which forces a full scan; rewriting as a range order_date >= '2026-01-01' AND order_date < '2027-01-01' lets the index work. Knowing that indexes speed reads but cost write and storage overhead rounds out the answer.

Interview note: Trap: "add indexes to every column?" No — each index slows inserts and updates and consumes space. Index the columns you actually filter, join and sort on.

What interviewers really test

SQL rounds reward the analyst who can predict exactly which rows a query returns and reach for the right tool — a window function over a self-join, a LEFT JOIN with an IS NULL filter over a NOT IN. Practice by writing complete queries against a small schema until joins, GROUP BY and window functions are automatic. Pair this page with the data cleaning questions, which lean heavily on SQL deduplication and NULL handling, and the experienced analyst set for how these queries scale up. The SQL learning path and a live mock interview will make the syntax disappear so you can focus on the logic.

Frequently Asked Questions

How important is SQL in a data analyst interview?
It is usually the single most important technical skill tested. Most analyst interviews include a live SQL screen where you write queries against sample tables, so joins, aggregation and window functions are non-negotiable to prepare.
What SQL topics come up most for analysts?
Joins (especially INNER vs LEFT), GROUP BY with HAVING, and window functions dominate. The second-highest-salary problem, finding duplicates, and running totals are near-guaranteed pattern questions across analyst interviews.
Do I need to know window functions as a data analyst?
Yes. Window functions such as ROW_NUMBER, RANK, and running SUM are now standard for ranking, deduplication and period-over-period analysis. Many analyst interviews specifically test whether you reach for a window function instead of a clumsy self-join.
What is the difference between WHERE and HAVING in SQL?
WHERE filters individual rows before grouping; HAVING filters groups after aggregation. You cannot use an aggregate like COUNT() in WHERE, and putting a non-aggregate row filter in HAVING is a common giveaway that a candidate does not understand execution order.
How do I prepare for a live SQL interview?
Practice writing complete queries by hand against a couple of sample schemas until joins, GROUP BY and window functions are automatic. Explain your query out loud as you write it — interviewers score your reasoning about which rows the query returns.

Want to Build Your Career in Data Analytics with AI?

Join CodeBegun and train with working industry engineers — View the Data Analytics curriculum

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 16 July 2026 LinkedIn
Chat with us