← Yahoo Interview Insights

Yahoo·Data Scientist·Technical Phone Screen·Intermediate

Intermediate
Jul 2026

Summary

SQL-heavy Data Scientist screen at Yahoo, five questions all built around a single transactions table. Nothing conceptually wild but the window function stuff got tricky fast and I wasn't as sharp on the revenue drop calculation as I wanted to be.

Questions Asked (5)

Q1

Given a transactions table with user_id, amount, and date columns, write a query that returns each user's total spend rounded to two decimal places.

Product Analytics & Metrics
Author's notes

Warmup question, pretty much just GROUP BY user_id with SUM and ROUND.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the table schema and any assumptions (e.g., date range, currency). Then write a SQL query that groups by user_id, sums the amount, and rounds to two decimal places. If the role emphasizes product analytics, mention how you'd validate and interpret the results.

Pro tip: Always state your assumptions about the data (e.g., no nulls, amounts in dollars) and mention that you'd check for edge cases like refunds or negative amounts. This shows you think beyond the basic query and understand real-world data issues.

1. Clarify requirements and assumptions

Ask about the table schema, data types, and any filters (e.g., date range, currency). Confirm whether 'total spend' includes refunds or only positive amounts.

2. Write the core SQL query

Use SELECT user_id, ROUND(SUM(amount), 2) AS total_spend FROM transactions GROUP BY user_id. Ensure the rounding is applied after aggregation.

3. Handle edge cases and data quality

Consider NULL amounts, negative values (refunds), and users with no transactions. Mention how you'd handle them (e.g., COALESCE, filtering, or including zero-spend users).

4. Validate and interpret results

Describe how you'd sanity-check the output (e.g., compare with total revenue, spot-check a few users) and what insights you might derive for product analytics.

Key Points to Mention

  • GROUP BY user_id to aggregate per user
  • SUM(amount) to calculate total spend
  • ROUND(..., 2) to round to two decimal places
  • Handling NULLs and negative amounts (refunds)
  • Considering date filters or time windows if relevant
  • Validating results against business metrics

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

Using the same transactions table, return the user_id(s) with the second-highest total spend.

Algorithms & Data StructuresProduct Analytics & Metrics
Author's notes

This is where it got a little annoying.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, aggregate total spend per user by summing transaction amounts grouped by user_id. Then rank users by total spend in descending order and select the user(s) whose rank equals 2, using either a window function like DENSE_RANK or a subquery with LIMIT/OFFSET. Ensure ties are handled correctly so all users with the second-highest total are returned.

Pro tip: Clarify whether 'second-highest' means the second distinct total (handling ties) or the second row after sorting, and mention that DENSE_RANK is the safest choice for the former. Also, explicitly state your assumption about excluding nulls or refunds if the table might contain them.

1. Clarify the metric and tie-handling

Confirm that total spend is the sum of transaction amounts per user and decide how to treat ties for the second-highest value. State whether you will return all users tied at that rank.

2. Aggregate spend per user

Write a subquery or CTE that groups by user_id and computes SUM(amount) as total_spend. Filter out any invalid or null amounts if necessary.

3. Rank users by total spend

Apply a window function such as DENSE_RANK() OVER (ORDER BY total_spend DESC) to assign ranks, ensuring that ties receive the same rank and no ranks are skipped.

4. Filter for the second-highest rank

Select user_id(s) where the rank equals 2. If using LIMIT/OFFSET instead, be careful to handle ties by first finding the second distinct total and then matching users to that total.

5. Validate and discuss edge cases

Check that the query returns the correct users when there are ties, fewer than two distinct totals, or null values. Mention how you would test the query on sample data.

Key Points to Mention

  • Use of window functions like DENSE_RANK or RANK to handle ties correctly
  • Aggregation with GROUP BY user_id and SUM(amount)
  • Difference between RANK, DENSE_RANK, and ROW_NUMBER in tie scenarios
  • Alternative approach using subquery with LIMIT/OFFSET and its limitations with ties
  • Handling of NULLs or negative amounts (refunds) in the transactions table
  • Performance considerations for large datasets (e.g., indexing, avoiding unnecessary sorting)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

List all users whose number of transactions is greater than the average transaction count across all users.

Product Analytics & Metrics
Author's notes

Used a HAVING clause with a subquery for the average.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the schema and definitions (e.g., what counts as a transaction, how to handle users with zero transactions). Then outline a SQL solution using a subquery or window function to compute the average transaction count per user and filter users above that average. Finally, discuss potential edge cases and performance considerations.

Pro tip: Mention that you would validate the result by checking the distribution of transaction counts and ensuring the average is computed correctly, especially if there are outliers or inactive users. This shows attention to data quality and business impact.

1. Clarify requirements and assumptions

Ask clarifying questions about the data model: which tables to use, how to define a transaction, and whether to include users with zero transactions. Confirm the expected output format.

2. Compute per-user transaction counts

Write a subquery or CTE that aggregates transactions by user, counting the number of transactions per user. Ensure all users are included, even those with zero transactions, if required.

3. Calculate the average transaction count

Compute the average of the per-user transaction counts. This can be done with a separate subquery or using a window function like AVG() OVER ().

4. Filter users above the average

Select users whose transaction count is greater than the computed average. Use a WHERE clause or a join with the average value.

5. Discuss edge cases and performance

Address handling of NULLs, users with no transactions, and potential performance issues with large datasets. Suggest indexing or partitioning if needed.

Key Points to Mention

  • Use of SQL aggregation functions (COUNT, AVG) and subqueries or CTEs.
  • Consideration of users with zero transactions and how they affect the average.
  • Window functions (e.g., AVG() OVER ()) as an alternative to subqueries.
  • Handling of NULL values and ensuring correct join logic.
  • Performance implications and optimization strategies for large datasets.
  • Validation of results by cross-checking with summary statistics or visualizations.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

For each date in the table, calculate the percentage drop in revenue compared to the previous day, and return only dates where the drop is 10% or more.

Product Analytics & MetricsRoot Cause Analysis
Author's notes

Hardest one for me.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the table schema and the definition of 'previous day' (e.g., consecutive dates or previous available date). Then use a window function like LAG to compute the previous day's revenue, calculate the percentage drop, and filter for drops >= 10%.

Pro tip: Mention that you would handle edge cases such as missing dates or zero revenue in the previous day to avoid division errors, and consider whether the analysis should be done in SQL or Python depending on the data size and environment.

1. Clarify requirements and data

Confirm the table structure, date granularity, and whether 'previous day' means the immediately preceding calendar day or the previous row in the dataset. Also check for missing dates or duplicate entries.

2. Compute previous day's revenue

Use a window function such as LAG(revenue) OVER (ORDER BY date) to retrieve the revenue from the previous day for each row.

3. Calculate percentage drop

Compute the drop as (previous_revenue - current_revenue) / previous_revenue * 100. Ensure you handle cases where previous_revenue is zero or null.

4. Filter and return results

Apply a WHERE clause to keep only rows where the drop is >= 10%, and select the date column (and possibly the drop percentage) as the final output.

5. Validate and discuss edge cases

Mention how you would validate the results (e.g., spot-check a few dates) and discuss handling of missing dates, zero revenue, or non-consecutive days.

Key Points to Mention

  • Use of window functions (LAG) to access previous row values
  • Definition of 'previous day' and handling of non-consecutive dates
  • Percentage drop formula and avoiding division by zero
  • Filtering condition for drops >= 10%
  • Edge cases: missing dates, zero revenue, null values
  • Validation of results and potential business interpretation

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q5

For every user, return their first purchase date and the total amount they spent on that specific day.

Product Analytics & MetricsData Modeling
Author's notes

MIN(date) partitioned by user in a window function, then join back to filter.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Clarify the table schema and define 'first purchase date' as the minimum transaction date per user. Then aggregate the total amount spent on that specific date, likely using a window function or subquery to filter transactions to each user's first date.

Pro tip: Mention that you would validate the result by checking for users with multiple purchases on their first day and ensuring the total amount is correctly summed, not just the first transaction.

1. Understand the data model

Identify the relevant tables (e.g., users, transactions) and columns (user_id, transaction_date, amount). Confirm that each row represents a transaction and that 'first purchase date' means the earliest transaction date per user.

2. Find first purchase date per user

Use a GROUP BY user_id with MIN(transaction_date) to get the first purchase date for each user. Alternatively, use a window function like ROW_NUMBER() or RANK() if you need to handle ties or additional columns.

3. Aggregate total amount on that date

Join the first purchase dates back to the transactions table on user_id and transaction_date, then SUM(amount) grouped by user_id and transaction_date. This ensures you capture all purchases made on that specific day.

4. Handle edge cases and validate

Consider users with no purchases (exclude or include with NULL/0), multiple purchases on the first day (sum all), and timezone considerations if dates are stored with timestamps. Validate by spot-checking a few users.

5. Write the final query

Combine steps into a single SQL query, using CTEs or subqueries for readability. For example: WITH first_dates AS (SELECT user_id, MIN(transaction_date) AS first_date FROM transactions GROUP BY user_id) SELECT t.user_id, t.transaction_date, SUM(t.amount) AS total_amount FROM transactions t JOIN first_dates f ON t.user_id = f.user_id AND t.transaction_date = f.first_date GROUP BY t.user_id, t.transaction_date;

Key Points to Mention

  • Use of MIN() or window functions to identify the first purchase date per user.
  • Joining the first purchase date back to the transactions table to filter relevant rows.
  • Aggregating with SUM() to get total amount spent on that specific day.
  • Handling users with no purchases (e.g., LEFT JOIN or filtering).
  • Considering timezone or timestamp truncation if dates include time components.
  • Validating results by checking for multiple transactions on the first day.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.