The short answer: data analyst interviews test whether you can turn messy data into a clear answer to a business question. Expect a SQL round (joins, aggregation, window functions), questions on Excel and a BI tool such as Power BI or Tableau, often Python or R with pandas, statistics (distributions, p-values, A/B tests), metrics and product sense, a case study (“revenue dropped 15%, why?”), and behavioral questions about working with stakeholders. The answers below are checked against the official documentation (PostgreSQL, Microsoft Excel and Power BI, pandas) and the American Statistical Association’s statement on p-values, with sources at the end. Every SQL query was run on PostgreSQL 18, and every pandas snippet on pandas 3.1.
What the data analyst interview process looks like
Most processes have four or five steps, though the order varies by company:
| Stage | What it tests | How to prepare |
|---|---|---|
| Recruiter screen | Motivation, experience, salary range | A two-minute story of your background and why this role |
| SQL or technical screen | Live SQL, sometimes Excel or Python | Practice joins, GROUP BY and window functions out loud |
| Take-home or case study | Cleaning, analysis and a recommendation | Answer the business question first, then show the work |
| Stakeholder or presentation round | Explaining results to non-analysts | Lead with the conclusion and one chart |
| Behavioral | Ownership, communication, handling ambiguity | Three or four STAR stories |
SQL questions
SQL is the most-tested skill for analysts. The examples use two tables:
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
country TEXT,
signup_date DATE
);
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
amount NUMERIC(10, 2)
);
Our SQL interview questions cover joins, NULL handling, indexes and query order in depth. These are the analyst-style questions that come up most.
“Calculate month-over-month revenue growth.”
WITH monthly AS (
SELECT date_trunc('month',
order_date) AS month,
SUM(amount) AS revenue
FROM orders
GROUP BY 1
)
SELECT month,
revenue,
ROUND(100.0 * (revenue
- LAG(revenue) OVER w)
/ LAG(revenue) OVER w, 1)
AS growth_pct
FROM monthly
WINDOW w AS (ORDER BY month)
ORDER BY month;
LAG() reads the previous month’s revenue from the ordered window. The first month has no previous value, so its growth is NULL, which is correct: don’t fake a zero.
“Find the top three customers by revenue in each country.”
WITH totals AS (
SELECT c.country,
o.customer_id,
SUM(o.amount) AS revenue
FROM orders o
JOIN customers c USING (customer_id)
GROUP BY 1, 2
),
ranked AS (
SELECT *,
DENSE_RANK() OVER (
PARTITION BY country
ORDER BY revenue DESC)
AS rnk
FROM totals
)
SELECT * FROM ranked
WHERE rnk <= 3
ORDER BY country, rnk;
Say which ranking function you chose and why: ROW_NUMBER() breaks ties arbitrarily, RANK() leaves gaps after ties (1, 1, 3), and DENSE_RANK() doesn’t (1, 1, 2). “Top three” with ties can return more than three rows, so confirm what the business wants.
“Keep only the latest order per customer.”
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY order_date DESC,
order_id DESC)
AS rn
FROM orders
) t
WHERE rn = 1;
ROW_NUMBER() partitioned by customer and ordered by date (newest first) numbers each customer’s orders, and rn = 1 keeps the latest. The second sort key, order_id, makes the result deterministic when two orders share a date.
“Compute a running total.”
SELECT order_date,
amount,
SUM(amount) OVER (
ORDER BY order_date, order_id
) AS running_total
FROM orders
ORDER BY order_date, order_id;
“What share of revenue comes from each country?”
SELECT c.country,
SUM(o.amount) AS revenue,
ROUND(100.0 * SUM(o.amount)
/ SUM(SUM(o.amount)) OVER (),
1) AS pct_of_total
FROM orders o
JOIN customers c USING (customer_id)
GROUP BY c.country
ORDER BY revenue DESC;
SUM(SUM(o.amount)) OVER () sums the grouped totals across all rows, so each country can be divided by the grand total in one query.
“What percentage of each monthly signup cohort ordered within 30 days?”
SELECT date_trunc('month',
c.signup_date) AS cohort,
COUNT(*) AS signups,
ROUND(100.0 * COUNT(*) FILTER (
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id
= c.customer_id
AND o.order_date
< c.signup_date + 30))
/ COUNT(*), 1) AS pct_30d
FROM customers c
GROUP BY 1
ORDER BY 1;
Cohort retention is a favorite at product companies. Define the window precisely (“within 30 days of signup”) and say how you treat customers who signed up too recently to have had 30 days.
“WHERE or HAVING?”
WHERE filters rows before grouping; HAVING filters groups after aggregation, so HAVING SUM(amount) > 1000 works and WHERE SUM(amount) > 1000 doesn’t. Filter in WHERE whenever you can, since it reduces the rows that get grouped.
Excel questions
“VLOOKUP or XLOOKUP?”
XLOOKUP is the modern lookup: it can return a column to the left or the right of the lookup column, does an exact match by default, and takes a value to show when nothing is found:
=XLOOKUP(A2, Products[ID],
Products[Price], "Not found")
VLOOKUP only looks up in the first column of the range and returns a column to its right, and if you leave out the last argument it does an approximate match, which silently returns wrong values on unsorted data. Always pass FALSE for an exact match. Microsoft notes that XLOOKUP isn’t available in Excel 2016 or Excel 2019, so INDEX with MATCH is still worth knowing for older files.
“What else do analysts use Excel for?”
- Pivot tables to summarize by category and date in seconds, and to spot-check totals from SQL.
SUMIFS,COUNTIFSandAVERAGEIFSfor conditional totals.- Dynamic array functions in Microsoft 365, such as
FILTER,UNIQUE,SORT, andGROUPBYfor a summary built by a formula. - Power Query to import and clean data with repeatable steps instead of manual edits.
- Python in Excel, available in Microsoft 365 for Windows, Mac and the web, to run pandas code inside a workbook.
A good answer mentions checking your work: reconcile totals against the source, and keep raw data separate from calculations.
Python and pandas questions
Python with pandas is now standard for analysts beyond the spreadsheet. pandas 3.0 (January 2026) made copy-on-write the default behavior and gave strings a dedicated str data type; pandas 3.1 came out on October 22, 2026. Our Python interview questions cover the language itself.
“How do you load and clean a dataset?”
import pandas as pd
df = pd.read_csv(
"orders.csv",
parse_dates=["order_date"])
df = df.drop_duplicates()
print(df.isna().sum())
# Drop rows we can't attribute
df = df.dropna(subset=["customer_id"])
# Keep unknowns visible, not hidden
df["country"] = (df["country"]
.fillna("Unknown"))
Look before you change anything: count missing values per column, check duplicates, and ask why data is missing before you drop or fill it. Filling missing values with an average can hide a broken pipeline.
“Summarize revenue by country.”
summary = (
df.groupby("country")
.agg(orders=("order_id", "count"),
revenue=("amount", "sum"),
avg_order=("amount", "mean"))
.sort_values("revenue",
ascending=False)
)
“Compute monthly revenue and growth.”
monthly = (
df.set_index("order_date")
.resample("MS")["amount"]
.sum()
)
growth = monthly.pct_change() * 100
resample("MS") groups by calendar month (labeled by the month’s start), and pct_change() compares each month with the previous one.
“Which customers never ordered?”
merged = customers.merge(
orders, on="customer_id",
how="left", indicator=True)
no_orders = merged[
merged["_merge"] == "left_only"]
indicator=True adds a _merge column that says whether each row matched (both) or came only from the left table (left_only), which is also a quick way to audit a join.
Power BI and Tableau questions
“What is a star schema, and why does Power BI want one?”
A star schema separates fact tables (events and numbers, such as sales lines) from dimension tables (the things you filter and group by: dates, products, customers). Microsoft’s Power BI guidance recommends it: each table should be clearly one or the other, and fact tables should load at a consistent grain. It keeps the model small, makes filters flow predictably from dimensions to facts, and keeps DAX simple.
“Measure or calculated column?”
A calculated column is computed row by row when the data is loaded or refreshed and stored in the model, so it uses memory and doesn’t respond to report filters. A measure is computed at query time in the current filter context, so its result changes as users slice the report. Totals, ratios and time comparisons belong in measures:
Total Sales =
SUMX(Sales,
Sales[Qty] * Sales[Price])
Sales LY =
CALCULATE(
[Total Sales],
SAMEPERIODLASTYEAR('Date'[Date])
)
“What does CALCULATE do?”
CALCULATE evaluates an expression in a modified filter context: it adds, replaces or removes filters before computing a measure. It’s the most important DAX function and the most common Power BI interview question, often followed by “explain row context versus filter context”. Row context is “the current row” (in a calculated column or an iterator such as SUMX); filter context is the set of filters coming from the report, slicers and CALCULATE.
“Import or DirectQuery?”
Import copies the data into Power BI’s in-memory model: fast and fully interactive, but only as fresh as the last refresh. DirectQuery sends queries to the source each time, so data is current, but performance depends on the source and some features are limited. Import is the usual default; DirectQuery fits very large or frequently changing data.
“What do Tableau interviews ask?”
Dimensions versus measures, discrete versus continuous fields, calculated fields, level of detail (LOD) expressions, which compute at a more detailed level (INCLUDE), a less detailed level (EXCLUDE) or a level independent of the view (FIXED), filters and the order Tableau applies them, extracts versus live connections, and dashboard design. Whatever the tool, explain why you chose each chart.
Statistics questions
“Mean or median?”
The mean uses every value, so a few extreme values pull it; the median is the middle value and resists outliers. For skewed data such as income, order values or session length, report the median (and often the mean too) and say why.
“What does a p-value mean?”
The American Statistical Association’s 2016 statement is the safest answer. A p-value shows how incompatible the data are with a specified statistical model, usually the null hypothesis of no effect. It doesn’t measure the probability that the hypothesis is true, or that the data came from chance alone, and it doesn’t measure the size or importance of an effect. Decisions shouldn’t rest only on whether p crosses 0.05. Report the effect size with a confidence interval.
“How would you run an A/B test?”
- Define one primary metric and the smallest change worth detecting, plus guardrail metrics that must not get worse.
- Estimate the sample size (from the baseline rate, minimum detectable effect, significance level and power), and fix the test duration in advance, covering full weekly cycles.
- Randomize users (not sessions) into control and treatment, and check that the split came out as planned.
- Don’t stop early the moment the result looks significant: repeated “peeking” inflates false positives.
- Analyze the effect with a confidence interval, check segments for surprises, and recommend a decision.
“Correlation or causation?”
Two metrics moving together doesn’t mean one causes the other: a third factor (seasonality, a marketing campaign, the type of customer) can drive both. Experiments establish causation; with observational data, say what else could explain the pattern and how you would test it.
“What is Simpson’s paradox?”
A trend that appears in every group can reverse when the groups are combined. The classic example is a 1986 study of kidney stone treatments: treatment A had a higher success rate for both small and large stones, but a lower rate overall, because A was used more often on the harder, large stones.
import pandas as pd
kidney = pd.DataFrame({
"treatment": ["A", "A", "B", "B"],
"stone": ["small", "large"] * 2,
"success": [81, 192, 234, 55],
"patients": [87, 263, 270, 80],
})
kidney["rate"] = (kidney["success"]
/ kidney["patients"])
print(kidney)
overall = kidney.groupby("treatment")[
["success", "patients"]].sum()
print(overall["success"]
/ overall["patients"])
Treatment A succeeds 93% of the time on small stones and 73% on large ones, beating B (87% and 69%), yet A’s overall rate is 78% against B’s 83%. Always check whether a mix shift between segments explains a change in an overall metric.
Metrics and product sense
“Which metrics would you use to measure a product’s health?”
Start from what the business sells and how it makes money, then pick a small set:
- Acquisition: new users, sign-up conversion, cost per acquisition.
- Engagement: daily or monthly active users, and DAU/MAU as a measure of stickiness.
- Retention: the share of a signup cohort still active after 7, 30 or 90 days.
- Revenue: conversion to paid, average order value, revenue per user, lifetime value.
- Guardrails: metrics that must not get worse, such as refunds, support tickets or page load time.
Define each metric precisely (who counts as “active”? which time zone?), because vague definitions cause most dashboard arguments.
“How would you measure the success of a new feature?”
State the feature’s goal, pick one primary metric that reflects it, add guardrails, decide the comparison (an A/B test if possible, otherwise a before-and-after with a control group), and say what result would make you recommend rolling back.
Case study: “Revenue dropped 15% last month. Why?”
Interviewers care about your structure more than the answer:
- Check the data first. Is the drop real? Look for tracking changes, missing data, late-arriving records, currency or time-zone issues.
- Clarify the metric. Gross or net revenue? Compared with last month or the same month last year? Seasonality can explain a month-over-month drop on its own.
- Decompose it. Revenue = customers × orders per customer × average order value. Which part moved?
- Segment. Split by region, channel, product, device, and new versus returning customers. A drop concentrated in one segment points to a cause.
- Look for events. Releases, price changes, outages, marketing changes, competitor moves.
- Recommend. State the most likely cause, how confident you are, and the next step to confirm or fix it.
Data cleaning and data quality
“How do you handle missing values?”
First find out why they’re missing: a broken pipeline, a field that’s optional, or a real “none”. Then choose: drop the rows (if few, and missing at random), fill them (with a default, a median, or the last known value for time series), or keep them as their own category (“Unknown”). Always report what you did, because each choice changes the result.
“How do you handle outliers?”
Investigate before removing: an outlier can be a data error (a price of 1,000,000 instead of 100.00) or your most important customer. Fix errors at the source, and for real extreme values, use medians, cap values, or analyze those cases separately, and state the rule.
“How do you make sure your numbers are right?”
Reconcile totals with a trusted source, check row counts after every join (an unexpected increase means duplicate keys), compare with last period’s numbers, and ask someone to review queries that feed important decisions.
Visualization and storytelling
| Question you’re answering | Chart |
|---|---|
| How do categories compare? | Bar chart, sorted |
| How does something change over time? | Line chart |
| What’s the share of a whole? | Stacked bar, or a pie with very few slices |
| How is a value distributed? | Histogram or box plot |
| Are two numbers related? | Scatter plot |
When you present, lead with the conclusion, show one chart that proves it, label it in plain language (“Repeat purchases fell 12% after the price change”), and end with the recommendation and its trade-offs.
Questions by level
- Entry-level and graduate: SQL basics (joins,
GROUP BY,HAVING), Excel lookups and pivot tables, mean versus median, a simple chart choice, “walk me through a project”, and why you want to be an analyst. - Mid-level: window functions, cohort retention, pandas cleaning and merges, DAX measures, A/B test design, metric definitions, and a case study.
- Senior: experiment pitfalls (peeking, multiple comparisons, novelty effects), metric frameworks, data modeling, influencing decisions without authority, and mentoring.
- Related roles: see our business analyst interview questions, data science interview prep and data engineer interview questions.
Behavioral questions for data analysts
Use the STAR method with a real example and a measurable result:
- “Tell me about an analysis that changed a decision. What did you recommend, and what happened?”
- “Describe a time the data was messy or incomplete. What did you do?”
- “Tell me about a time a stakeholder disagreed with your findings.”
- “How do you prioritize when several teams ask you for reports at once?”
- “Tell me about a mistake in your analysis. How did you find it and fix it?”
More: our SQL interview questions, Python interview questions and financial analyst interview questions.
Frequently asked questions
What questions are asked in a data analyst interview?
What SQL do I need for a data analyst interview?
How do I answer a data analyst case study?
What is the difference between VLOOKUP and XLOOKUP?
What does a p-value mean?
Do data analysts need Python?
Can Huru help me practice data analyst interview questions?
Sources
- PostgreSQL documentation, Window functions and Aggregate expressions and FILTER. All SQL in this guide was run on PostgreSQL 18 on 4 November 2026.
- Microsoft Support, XLOOKUP function (not available in Excel 2016 and 2019), VLOOKUP function (first column, approximate match by default), GROUPBY function and Introduction to Python in Excel. Read on 4 November 2026.
- Microsoft Learn, Understand star schema and the importance for Power BI, DAX overview (calculated columns, measures, row and filter context), CALCULATE and DirectQuery in Power BI. Read on 4 November 2026.
- pandas, What’s new in 3.0.0 (copy-on-write,
strdata type; released 21 January 2026) and pandas on PyPI (3.1.0 on 22 October 2026). All pandas code in this guide was run on pandas 3.1.0 and Python 3.14 on 4 November 2026. - Tableau Help, Create level of detail expressions in Tableau. Read on 4 November 2026.
- Wasserstein and Lazar, The ASA Statement on p-Values: Context, Process, and Purpose, American Statistical Association, 2016.
- Charig and others, “Comparison of treatment of renal calculi by open surgery, percutaneous nephrolithotomy, and extracorporeal shockwave lithotripsy”, BMJ, 1986 (the kidney stone data behind the Simpson’s paradox example).