← Meta Interview Insights

Meta·Data Scientist·Technical Phone Screen·Senior

Senior
Jul 2026

Summary

SQL-heavy technical screen for a Data Scientist role at Meta. Five tasks back to back, all on the same sales schema, ranging from basic aggregations to Pearson correlation in pure SQL. The complexity ramp was real and I was not ready for the later questions.

Questions Asked (5)

Q1

Given a deals table and a reps table, write SQL to compute per-rep metrics for Q2 2025: number of closed deals, wins, win rate, average deal amount, and average sales cycle in days. Filter to closed-stage deals with amount > 0, and sort by win rate descending with ties broken by average deal amount.

Product Analytics & MetricsData Modeling
Author's notes

This one I actually felt okay about.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the schema and definitions (e.g., closed-stage, win condition, sales cycle). Then write a single SQL query that filters deals to Q2 2025, closed stages, and amount > 0, joins with reps, and computes the required metrics using conditional aggregation. Finally, sort the results by win rate descending and average deal amount descending.

Pro tip: Use conditional aggregation (e.g., SUM(CASE WHEN is_win THEN 1 ELSE 0 END)) to compute wins and closed deals in one pass, and be explicit about how you handle NULLs or zero denominators for win rate and average sales cycle.

1. Clarify schema and definitions

Confirm table structures, stage values, win condition, and sales cycle calculation. Ensure you understand what 'closed-stage' means and how to identify wins.

2. Filter and join data

Filter deals to Q2 2025 (April 1 - June 30), closed stages, and amount > 0. Join with reps table to get rep information.

3. Compute per-rep metrics

Use conditional aggregation to calculate number of closed deals, wins, win rate, average deal amount, and average sales cycle in days. Handle division by zero for win rate.

4. Sort and format output

Sort results by win rate descending, then by average deal amount descending. Ensure all metrics are properly rounded or formatted as needed.

Key Points to Mention

  • Use conditional aggregation (CASE WHEN) to compute wins and closed deals in a single query.
  • Define win rate as wins divided by closed deals, with a safeguard against division by zero.
  • Calculate sales cycle as the difference between close date and created date (or appropriate dates) in days.
  • Filter deals to Q2 2025 using date ranges (e.g., deal_date BETWEEN '2025-04-01' AND '2025-06-30').
  • Join deals with reps on rep_id to group metrics by rep.
  • Sort by win rate DESC, then average deal amount DESC to break ties.

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

Q2

Deduplicate a touches table by keeping the smallest touch_id per (account_id, touch_date, channel), then define each account's first touch channel in 2025. Join that to 2025 closed deals and produce a report showing first_touch_channel, rep segment, closed deals, wins, and win rate. Include both per-segment rows and a channel-level overall row in a single query.

Data ModelingProduct Analytics & Metrics
Author's notes

This is where things got messy for me.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the schema and business definitions, then break the problem into three CTEs: deduplicated touches, first touch per account in 2025, and closed deals. Use a UNION ALL to combine per-segment aggregates with a channel-level overall row, ensuring win rate is computed as wins divided by closed deals.

Pro tip: Explicitly state that you would validate the deduplication logic and handle ties or missing data before writing the final query, and mention that you'd check for accounts with no touches or deals to avoid misleading win rates.

1. Clarify requirements and schema

Ask about table structures, definitions of 'rep segment', 'closed deals', and 'wins', and confirm that 'first touch channel' means the channel of the earliest touch in 2025.

2. Deduplicate touches

Use ROW_NUMBER() OVER (PARTITION BY account_id, touch_date, channel ORDER BY touch_id) to keep the smallest touch_id per group.

3. Identify first touch channel per account

From deduplicated touches, filter to 2025 and use ROW_NUMBER() OVER (PARTITION BY account_id ORDER BY touch_date, touch_id) to select the earliest touch per account.

4. Join with closed deals and aggregate

Join first touch to 2025 closed deals on account_id, then group by first_touch_channel and rep_segment to compute closed deals, wins, and win rate.

5. Combine segment and overall rows

Use UNION ALL to append a channel-level overall row (grouped only by first_touch_channel) to the per-segment results, ensuring consistent column order and data types.

Key Points to Mention

  • Use of window functions (ROW_NUMBER) for deduplication and first-touch identification.
  • Handling of ties in touch_id or touch_date (e.g., deterministic ordering).
  • Definition of win rate as wins / closed deals, and potential division by zero.
  • Inclusion of accounts with no touches or no deals (e.g., LEFT JOIN vs INNER JOIN).
  • Use of UNION ALL to combine per-segment and overall rows, with proper labeling.
  • Validation steps: checking row counts, duplicates, and edge cases before finalizing.

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

Q3

For each rep, compute the Pearson correlation between prior-week call count and current-week win rate across Q2 2025 weeks. The query should build weekly call counts, build weekly win rates, lag the call count by one week within rep, then aggregate using the closed-form Pearson formula. Exclude reps with fewer than 5 weeks of overlapping data.

Product Analytics & MetricsAlgorithms & Data Structures
Author's notes

I stared at this for a solid 30 seconds before writing anything.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Break the problem into four stages: build weekly call counts per rep, build weekly win rates per rep, lag call counts by one week within each rep, and then compute Pearson correlation using the closed-form formula. Ensure you filter to Q2 2025 weeks and exclude reps with fewer than 5 overlapping weeks. Use window functions for lagging and aggregation, and handle edge cases like zero variance.

Pro tip: Always verify that your lagged call count aligns with the correct week (e.g., prior week's calls predicting current week's win rate) and that you're using the same set of weeks for both metrics. Also, consider the business implication: a positive correlation might suggest that increased call activity drives wins, but be cautious about causality.

1. Build weekly call counts

Aggregate call data to get total calls per rep per week for Q2 2025. Ensure weeks are defined consistently (e.g., using date_trunc).

2. Build weekly win rates

Compute win rate per rep per week as wins divided by total opportunities (or deals) for that week. Handle division by zero.

3. Lag call counts within rep

Use a window function (e.g., LAG) partitioned by rep and ordered by week to shift call counts by one week, so each row has prior-week calls and current-week win rate.

4. Compute Pearson correlation per rep

For each rep, calculate Pearson correlation using the closed-form formula: (n*Σxy - Σx*Σy) / sqrt((n*Σx² - (Σx)²)*(n*Σy² - (Σy)²)). Exclude reps with fewer than 5 overlapping weeks.

Key Points to Mention

  • Use of window functions for lagging and aggregation
  • Handling of weeks with no calls or no deals (e.g., zero win rate or missing data)
  • Definition of win rate: wins / total opportunities, and how to treat ties or no-shows
  • Closed-form Pearson formula and its components (n, Σx, Σy, Σxy, Σx², Σy²)
  • Filtering for Q2 2025 and ensuring overlapping weeks between call counts and win rates
  • Exclusion criteria: reps with fewer than 5 weeks of data
  • Potential pitfalls: zero variance leading to division by zero, and the difference between correlation and causation

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

Q4

Write three separate data quality checks: find deals where closed_at is earlier than created_at, find accounts whose first touch date is after their first deal close date, and find deals whose region does not match their account's region.

Root Cause AnalysisData Modeling
Author's notes

Relief after the Pearson question.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the data model and table relationships, then write each check as a separate SQL query that joins the relevant tables and applies the condition. For each check, explain the logic, potential edge cases, and how you would validate the results.

Pro tip: Mention that you would add a tolerance for timezone differences or data entry delays, and that you would run these checks regularly as part of a data quality monitoring pipeline.

1. Understand the data model

Identify the tables involved (e.g., deals, accounts) and their key columns (created_at, closed_at, first_touch_date, region). Clarify relationships and join keys.

2. Write the first check

For deals where closed_at < created_at, write a simple SELECT with a WHERE clause on the deals table. Consider if closed_at can be NULL.

3. Write the second check

For accounts whose first touch date is after their first deal close date, join accounts to deals, group by account, and compare MIN(first_touch_date) with MIN(closed_at).

4. Write the third check

For deals whose region does not match their account's region, join deals to accounts on account_id and compare region fields.

5. Discuss validation and monitoring

Explain how you would validate the checks (e.g., sample records, expected counts) and suggest automating them as part of a data quality dashboard.

Key Points to Mention

  • Use of proper JOINs and aliasing to avoid ambiguity
  • Handling of NULL values and timezone considerations
  • Importance of defining 'first touch date' and 'first deal close date' clearly
  • Potential need for data type casting or date formatting
  • Automating checks and setting up alerts for failures
  • Documenting assumptions and edge cases

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

Q5

As of a fixed reference date, find the top 3 reps by distinct accounts touched via calls in the last 7 days. Apply the same deduplication rule as before. Break ties by total call count, then by lower rep_id.

Product Analytics & Metrics
Author's notes

Mostly execution at this point.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, clarify the deduplication rule and the fixed reference date. Then, filter calls to the last 7 days, deduplicate accounts per rep, count distinct accounts and total calls, and rank reps by distinct accounts, breaking ties by total calls and then lower rep_id.

Pro tip: Explicitly state your assumptions about the deduplication rule and reference date, and mention how you would handle ties and edge cases like reps with no calls.

1. Clarify requirements

Confirm the deduplication rule, the fixed reference date, and the definition of 'last 7 days' (e.g., including or excluding the reference date).

2. Filter and deduplicate

Filter call records to the last 7 days from the reference date. Apply the deduplication rule to ensure each account is counted only once per rep.

3. Aggregate metrics

For each rep, compute the number of distinct accounts touched and the total number of calls made in the period.

4. Rank and select top 3

Sort reps by distinct accounts descending, then by total calls descending, then by rep_id ascending. Select the top 3.

5. Validate and present

Check for ties, missing data, or anomalies. Present the top 3 reps with their metrics and explain the tie-breaking logic.

Key Points to Mention

  • Deduplication rule: ensure each account is counted once per rep, even if multiple calls occurred.
  • Fixed reference date: use the given date as the anchor for the 7-day window.
  • Tie-breaking: first by total call count (descending), then by lower rep_id (ascending).
  • Edge cases: reps with zero calls, accounts touched by multiple reps, and data quality issues.
  • SQL implementation: use window functions or subqueries to deduplicate and rank.
  • Business context: why distinct accounts matter more than raw call volume for this metric.

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