← TikTok Interview Insights

TikTok·Data Scientist·Technical Phone Screen·Intermediate

IntermediatePrefer not to say
Jun 2026

Summary

SQL-heavy data science interview at TikTok, four questions all centered on a food-delivery marketplace schema. The problems escalated from basic aggregation to window functions and quartile bucketing, which felt like a lot to get through in one sitting.

Questions Asked (4)

Q1

For each calendar month, what percentage of distinct customers placed more than 30 orders that month?

Product Analytics & MetricsData Modeling
Author's notes

Straightforward once you break it into two steps: count orders per customer per month, then aggregate at the month level.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Clarify the metric definition and data model, then write a SQL query that aggregates orders per customer per month, filters for >30 orders, and computes the percentage of distinct customers meeting that threshold relative to all distinct customers that month. Validate with edge cases and consider performance optimizations for large datasets.

Pro tip: Explicitly state your assumptions about what constitutes an 'order' (e.g., completed vs. all orders) and whether the denominator includes all customers or only those with at least one order that month; this shows attention to detail and prevents misinterpretation.

1. Clarify the metric and assumptions

Define 'order' (e.g., completed orders), 'distinct customer' (unique user ID), and the time window (calendar month). Confirm whether the denominator is all customers or only those with orders that month.

2. Identify relevant tables and fields

Locate the orders table with fields like order_id, customer_id, order_date, and status. Ensure you have a way to filter valid orders (e.g., status = 'completed').

3. Aggregate orders per customer per month

Write a subquery or CTE that groups by customer_id and month, counting distinct orders (or order rows) to get order_count per customer per month.

4. Compute the percentage

For each month, count distinct customers with order_count > 30, and divide by the total distinct customers that month (either all customers or those with orders). Multiply by 100 for percentage.

5. Validate and optimize

Check results for edge cases (e.g., months with no customers, customers with exactly 30 orders). Consider indexing or partitioning strategies for large-scale data.

Key Points to Mention

  • Definition of 'order' and 'distinct customer' (e.g., completed orders, unique user IDs)
  • Handling of time zones and month boundaries (e.g., using date_trunc or equivalent)
  • Denominator choice: all customers vs. only customers with orders that month
  • SQL techniques: GROUP BY, COUNT(DISTINCT), subqueries/CTEs, window functions if needed
  • Edge cases: customers with exactly 30 orders, months with zero orders, data quality issues
  • Performance considerations for large datasets (e.g., partitioning, indexing)

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

Q2

For each month, find the customer(s) with the highest order count among those who placed 30 or fewer orders. Then, as a follow-up, find the single customer with the most total orders across all months with no exclusion.

Product Analytics & MetricsAlgorithms & Data Structures
Author's notes

The exclusion filter tripped me up a bit.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Clarify the schema and definitions (order count per customer per month, handling ties, and whether '30 or fewer' is inclusive). Then outline a SQL solution using window functions: first filter customers with monthly order count ≤ 30, rank them per month by order count descending, and select the top rank(s). For the follow-up, remove the filter and find the customer with the maximum total orders across all months.

Pro tip: Explicitly discuss tie-handling for the monthly top customers (e.g., using RANK() to return all ties) and mention that the follow-up requires a simple aggregation without the 30-order limit, showing you can adapt the query logic.

1. Clarify requirements and schema

Ask about the table structure (e.g., orders table with customer_id, order_date, order_id) and confirm definitions: monthly order count per customer, '30 or fewer' inclusive, and how to handle ties for the highest count.

2. Compute monthly order counts per customer

Write a subquery or CTE that groups orders by customer and month (using DATE_TRUNC or EXTRACT) and counts orders, producing columns like customer_id, month, order_count.

3. Filter and rank for the first part

Filter the monthly counts to order_count ≤ 30, then use a window function (e.g., RANK() OVER (PARTITION BY month ORDER BY order_count DESC)) to identify the top customer(s) per month, returning all ties if needed.

4. Solve the follow-up without exclusion

Remove the ≤30 filter and aggregate total orders per customer across all months (SUM(order_count) or COUNT(*)), then select the customer with the maximum total orders, handling ties if necessary.

5. Validate and discuss edge cases

Mention potential edge cases: months with no qualifying customers, customers with zero orders, ties for top spot, and performance considerations for large datasets (e.g., indexing, partitioning).

Key Points to Mention

  • Use of window functions like RANK() or DENSE_RANK() to handle ties in monthly top customers.
  • Inclusive interpretation of '30 or fewer' (i.e., ≤ 30).
  • Difference between the two parts: first filters by monthly order count, second aggregates total orders without limit.
  • Handling of months with no customers meeting the criteria (e.g., return no rows or NULL).
  • Efficiency considerations: pre-aggregating monthly counts before ranking, and using appropriate indexes.
  • Clarification of 'total orders' as sum of monthly counts or overall count of orders.

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

Q3

For a given restaurant, compute its monthly total sales in 2021 and the month-over-month change, showing only months that have a prior month to compare against. Follow-up: how would you extend this to all restaurants?

Product Analytics & MetricsData Modeling
Author's notes

LAG window function, pretty standard.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the schema and assumptions (e.g., sales table with restaurant_id, date, amount). Then write a SQL query that aggregates monthly sales for 2021, uses LAG to get previous month's sales, computes the difference, and filters out months without a prior month. For the follow-up, generalize by partitioning by restaurant_id and using the same logic.

Pro tip: Mention that you would handle missing months carefully—if a month has no sales, it might be absent from the data, so you may need to generate a complete date spine to correctly compute month-over-month changes. Also, clarify whether 'month-over-month change' means absolute difference or percentage change.

1. Clarify requirements and data schema

Ask about the table structure (e.g., sales transactions with restaurant_id, date, amount) and confirm that 'monthly total sales' means sum of sales per month. Clarify if the change is absolute or percentage, and whether to include only months with a prior month in the same year.

2. Aggregate monthly sales for 2021

Write a subquery or CTE that groups by month (using DATE_TRUNC or EXTRACT) and sums sales for the given restaurant, filtering for year 2021.

3. Compute month-over-month change using window function

Use LAG(sales) OVER (ORDER BY month) to get previous month's sales, then calculate the difference (or percentage change). Ensure the window is ordered correctly.

4. Filter out months without a prior month

Exclude rows where the previous month's sales is NULL (i.e., the first month). This can be done with a WHERE clause on the LAG result.

5. Extend to all restaurants

Add restaurant_id to the GROUP BY and PARTITION BY clauses. The window function becomes LAG(sales) OVER (PARTITION BY restaurant_id ORDER BY month). Then filter similarly.

Key Points to Mention

  • Use of window functions like LAG to access previous row's value
  • Handling of missing months (date spine or calendar table) to avoid incorrect MoM calculations
  • Difference between absolute change and percentage change, and how to compute each
  • Partitioning by restaurant_id for the follow-up to compute per-restaurant MoM
  • Filtering out the first month (or any month without a prior month) using WHERE previous_sales IS NOT NULL
  • Performance considerations: indexing on date and restaurant_id, and avoiding unnecessary sorting

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

Q4

Each month, rank restaurants into four buckets by that month's total sales. Then compute the percentage of distinct customers who placed at least one order from a bottom-quartile restaurant in that month.

Product Analytics & MetricsData ModelingRoot Cause Analysis
Author's notes

This one took me a minute to structure mentally.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, clarify the business context and metric definitions, especially how to handle ties and edge cases. Then, outline a step-by-step SQL or Python approach: aggregate monthly sales per restaurant, rank restaurants into quartiles, identify customers who ordered from bottom-quartile restaurants, and compute the percentage of distinct customers. Finally, discuss potential pitfalls and validation checks.

Pro tip: Mention the importance of defining 'bottom quartile' precisely (e.g., using NTILE(4) or percentile thresholds) and how tie-breaking rules can affect results. Also, highlight that this metric could be used to monitor restaurant partner health and customer segmentation.

1. Clarify Definitions and Assumptions

Confirm what 'total sales' means (e.g., sum of order amounts), the time period (monthly), and how to handle ties in ranking. Ask about the granularity of data and whether 'distinct customers' are identified by user ID.

2. Aggregate Monthly Sales per Restaurant

Write a query to sum sales for each restaurant for each month. Ensure you include all restaurants with sales in that month.

3. Rank Restaurants into Quartiles

Use a window function like NTILE(4) to assign each restaurant to a quartile based on monthly sales. The bottom quartile is quartile 4 (if ordered ascending) or quartile 1 (if ordered descending).

4. Identify Customers Ordering from Bottom-Quartile Restaurants

Join the quartile assignments back to the orders table to find all orders placed at bottom-quartile restaurants in that month. Then, extract distinct customer IDs.

5. Compute the Percentage

Calculate the percentage as (number of distinct customers who ordered from bottom-quartile restaurants) / (total distinct customers who ordered in that month) * 100. Present results per month.

Key Points to Mention

  • Use of window functions (e.g., NTILE) for quartile ranking
  • Handling ties in sales ranking (e.g., using RANK or DENSE_RANK with thresholds)
  • Definition of 'distinct customers' and ensuring correct counting
  • Time period alignment: monthly aggregation and ensuring orders fall within the month
  • Edge cases: months with few restaurants, missing data, or zero sales
  • Validation: sanity checks like ensuring percentages are between 0 and 100, and comparing with overall customer distribution

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