← Pinterest Interview Insights

Pinterest·Data Scientist·Technical Phone Screen·Senior

Senior
Jun 2026

Summary

Pinterest data scientist interview with a brutal single SQL problem covering four sub-tasks at once. Window functions, rolling retention, ARPU by channel, edge cases, all in one script. Left feeling like I'd either nailed it or completely missed something obvious.

Questions Asked (4)

Q1

Given three tables (users, sessions, orders), write a single SQL script using CTEs and window functions that computes 7-day rolling retention for each calendar day in August 2025: among users who signed up on or before day D, what fraction had at least one session in the 7-day window ending on D?

Product Analytics & MetricsData Modeling
Author's notes

This is the part that tripped me up most.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by defining the cohort of users who signed up on or before each day D in August 2025. Then, for each day D, compute the number of users in that cohort who had at least one session in the 7-day window ending on D, and divide by the total cohort size. Use CTEs to organize the logic and window functions to handle the rolling window and cumulative counts.

Pro tip: Clarify whether '7-day rolling retention' means a rolling 7-day window (e.g., days D-6 to D) or a fixed 7-day period after signup; the former is more common for daily retention metrics. Also, consider edge cases like users with no sessions and ensure the denominator includes all users who signed up on or before D, not just those active.

1. Generate date spine for August 2025

Create a CTE with all calendar days in August 2025 to ensure every day is represented, even if there are no sessions or signups.

2. Identify eligible users per day

For each day D, determine the set of users who signed up on or before D. This can be done by joining the date spine with the users table and filtering signup_date <= D.

3. Compute active users in 7-day window

For each day D and each eligible user, check if they had at least one session in the 7-day window ending on D (D-6 to D). Use a window function or a self-join to aggregate sessions.

4. Calculate retention rate

Divide the number of active users in the window by the total number of eligible users for each day D, yielding the 7-day rolling retention rate.

Key Points to Mention

  • Definition of 7-day rolling retention: fraction of users who signed up on or before D and had at least one session in the 7-day window ending on D.
  • Use of CTEs to break down the problem: date spine, eligible users, active users, final aggregation.
  • Window functions to compute rolling counts or to identify sessions within the window (e.g., using RANGE BETWEEN INTERVAL '6 days' PRECEDING AND CURRENT ROW).
  • Handling of users with no sessions: ensure they are counted in the denominator but not in the numerator.
  • Performance considerations: indexing on date columns, avoiding cross joins, and using appropriate aggregation.
  • Edge cases: days at the beginning of August may have incomplete 7-day windows if data starts before August; clarify if the window should extend into July.

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

Q2

For each user, compute their first purchase date, the number of days between signup and first purchase, and prove via ROW_NUMBER or an equivalent window approach (not MIN subqueries) that the sum of orders strictly before the first purchase is zero.

Data ModelingAlgorithms & Data Structures
Author's notes

The 'prove it via ROW_NUMBER' constraint is what makes this non-trivial.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Use a window function like ROW_NUMBER() partitioned by user and ordered by purchase date to identify the first purchase per user, then compute the days between signup and that first purchase. To prove the sum of orders strictly before the first purchase is zero, use a windowed SUM() over the same partition and order, checking that the cumulative sum up to the row before the first purchase is zero.

Pro tip: Explicitly state that you are avoiding MIN() subqueries to ensure a single table scan and better performance, and mention that the ROW_NUMBER approach is more scalable for large datasets like Pinterest's.

1. Identify first purchase per user

Use ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY purchase_date) to assign a row number to each purchase, where row number 1 indicates the first purchase.

2. Compute days between signup and first purchase

Join the signup date and the first purchase date (where row number = 1) and calculate the date difference in days.

3. Prove sum of orders before first purchase is zero

Use a windowed SUM() OVER (PARTITION BY user_id ORDER BY purchase_date ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) to compute the cumulative sum of orders before the current row, and verify it is zero for the first purchase row.

4. Combine results and validate

Combine the first purchase date, days to first purchase, and the zero-sum proof into a final result set, ensuring all users are included even if they have no purchases (using LEFT JOIN or equivalent).

Key Points to Mention

  • Use of ROW_NUMBER() to identify first purchase without subqueries
  • Windowed SUM() with ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING to prove zero sum
  • Handling users with no purchases (e.g., LEFT JOIN or COALESCE)
  • Performance benefits of window functions over MIN() subqueries
  • Date functions for calculating days between signup and first purchase (e.g., DATEDIFF)
  • Partitioning by user_id and ordering by purchase_date to ensure correct sequencing

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

Q3

Compute the top 3 acquisition channels by 7-day ARPU over the window August 26 to September 1, 2025, where ARPU is total order revenue divided by number of users from that channel who had at least one session in that window.

Product Analytics & MetricsA/B Testing & Experimentation
Author's notes

Felt more straightforward than the retention part.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, clarify the definitions and assumptions: what counts as an acquisition channel, how to attribute users to channels, and whether revenue is attributed to the user or the order. Then outline a SQL-based approach that joins user sessions, orders, and channel attribution within the specified window, computes ARPU per channel, and ranks the top 3.

Pro tip: Explicitly state that you would validate the data for edge cases like users with multiple channels or orders outside the window, and mention that you'd check for statistical significance or confidence intervals if the differences between channels are small.

1. Clarify Definitions and Assumptions

Confirm what constitutes an acquisition channel (e.g., paid search, organic, referral), how users are attributed to channels (first-touch, last-touch), and whether revenue is attributed to the user or the order. Also clarify if ARPU is calculated per user or per session.

2. Identify Relevant Tables and Fields

Locate tables for user sessions, orders, and channel attribution. Ensure you have fields like user_id, session_date, order_revenue, and channel. Confirm that the session window is August 26 to September 1, 2025, inclusive.

3. Filter and Join Data

Filter sessions to the specified window, then join with orders on user_id and with channel attribution. Be careful to avoid double-counting revenue if a user has multiple orders or sessions.

4. Compute ARPU per Channel

For each channel, calculate total order revenue (sum of revenue from orders placed by users in that channel during the window) and divide by the number of unique users from that channel who had at least one session in the window.

5. Rank and Present Top 3

Sort channels by ARPU descending and select the top 3. Present the results with clear labels and note any caveats or assumptions made.

Key Points to Mention

  • Definition of acquisition channel and attribution logic (e.g., first-touch vs. last-touch).
  • Handling of users with multiple sessions or orders (deduplication, revenue attribution).
  • Time window inclusivity and timezone considerations.
  • Treatment of users with no orders (they contribute to denominator but not numerator).
  • Potential data quality issues: missing channel data, bot traffic, or test accounts.
  • Statistical significance or confidence intervals when comparing ARPU across channels.

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

Q4

Handle edge cases within the same SQL script: users with no sessions, multiple sessions on the same day, multiple orders on the same day, users who signed up after the analysis window, and UTC timezone assumptions for all timestamps. Where in the query does each case get handled?

Data ModelingTechnical Trade-offs
Author's notes

They wanted inline comments in the SQL explaining each.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Walk through the SQL script clause by clause (CTEs, JOINs, WHERE, GROUP BY, HAVING) and explicitly state where each edge case is handled, using defensive SQL patterns like LEFT JOINs, COALESCE, and date truncation. Emphasize that timezone normalization should happen early, ideally in a base CTE, so all downstream logic operates on UTC. Frame the answer as a design narrative that balances correctness with readability and performance.

Pro tip: Mention that you would add data quality checks or assertions (e.g., counts of users with no sessions) to validate edge case handling before trusting the results. This shows production maturity and prevents silent data issues.

1. Normalize timestamps to UTC upfront

In the first CTE, convert all timestamp columns to UTC using AT TIME ZONE or equivalent, ensuring consistent timezone handling. Document the assumption that source timestamps are in a known timezone (e.g., local or UTC) and state the conversion explicitly.

2. Handle users with no sessions and late signups

Use a LEFT JOIN from users to sessions so users with no sessions are retained, and filter signup_date <= analysis_end_date in the WHERE clause or a dedicated CTE to exclude users who signed up after the window. This ensures the denominator includes all eligible users.

3. Deduplicate multiple sessions or orders per day

Use a subquery or CTE with ROW_NUMBER() or GROUP BY user_id, DATE(session_ts) to collapse multiple events per day into one, or aggregate metrics (e.g., COUNT(DISTINCT session_id)) to avoid double-counting. Apply the same logic for orders.

4. Apply window and aggregation logic

In the final SELECT, filter events to the analysis window (e.g., session_ts BETWEEN start AND end), group by user and date as needed, and compute metrics. Use COALESCE to replace NULLs from LEFT JOINs with zeros for users with no activity.

5. Validate edge cases with checks

Add a validation step (e.g., separate queries or comments) to confirm counts of users with no sessions, multiple sessions per day, and late signups are handled as expected. This demonstrates thoroughness and catches logic errors.

Key Points to Mention

  • Use LEFT JOIN from users to sessions to retain users with no sessions, and COALESCE to handle NULL metrics.
  • Filter signup_date <= analysis_end_date to exclude users who signed up after the window, and consider whether to include them as zero-activity users.
  • Deduplicate multiple sessions/orders per day using ROW_NUMBER() or GROUP BY user_id, DATE(timestamp) to avoid inflating counts.
  • Normalize all timestamps to UTC in a base CTE using AT TIME ZONE, and document the assumption about source timezone.
  • Use DATE_TRUNC or DATE to bucket events by day after UTC conversion, ensuring consistent daily aggregation.
  • Add data quality checks (e.g., counts of edge cases) to validate the query before trusting results.

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