← Newyorktimes Interview Insights

Newyorktimes·Data Analyst·Technical Phone Screen·Intermediate

IntermediatePrefer not to say
May 2026Remote

Summary

SQL-heavy technical screen for a Data Analyst role at the New York Times, focused entirely on a page views fact table in BigQuery. Four queries back to back, each with its own wrinkle around NULLs, window functions, or aggregation grain. Felt more like a take-home that someone decided to do live.

Questions Asked (4)

Q1

Given a page_views table in BigQuery, write a query that returns mobile vs desktop unique contents viewed alongside total view events for each device group.

Product Analytics & MetricsData Modeling
Author's notes

The NULL handling is what trips people up here.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the table schema and definitions of 'unique contents' and 'view events'. Then write a SQL query that groups by device type (mobile vs desktop), counts distinct content IDs for unique contents, and counts all rows for total view events. Use conditional aggregation or a CASE statement to handle device grouping if needed.

Pro tip: Mention that you would confirm whether 'unique contents' means distinct content IDs per device group or overall, and whether view events should include all rows or only valid views. Also, consider using APPROX_COUNT_DISTINCT for large datasets to improve performance.

1. Clarify requirements and schema

Ask about the table columns (e.g., device_type, content_id, user_id, timestamp) and define 'unique contents' and 'view events'. Confirm if device_type values are exactly 'mobile' and 'desktop' or need mapping.

2. Plan the aggregation

Decide to group by device type and compute two metrics: COUNT(DISTINCT content_id) for unique contents and COUNT(*) for total view events. Consider if any filters (e.g., date range) are needed.

3. Write the SQL query

Use a GROUP BY on device_type with COUNT(DISTINCT content_id) AS unique_contents and COUNT(*) AS total_views. If device_type needs normalization, use a CASE expression to create a device_group column.

4. Validate and optimize

Check for NULLs or unexpected device types, and consider using APPROX_COUNT_DISTINCT for scalability. Ensure the query returns one row per device group.

Key Points to Mention

  • Use COUNT(DISTINCT content_id) to calculate unique contents per device group.
  • Use COUNT(*) or COUNT(view_id) to calculate total view events.
  • Group by device_type (or a derived device_group) to separate mobile and desktop.
  • Handle potential NULL or unexpected device types with CASE or WHERE clauses.
  • Consider performance implications and use APPROX_COUNT_DISTINCT if exact distinct count is not required.
  • Clarify whether 'unique contents' means distinct content per device group or overall, and whether view events include all rows or only valid views.

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

Q2

For each device group, find the top 3 hours of the day by view volume using window functions.

Product Analytics & MetricsAlgorithms & Data Structures
Author's notes

Got the RANK vs DENSE_RANK question almost immediately after I wrote it.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by aggregating view volume per device group and hour, then use a window function like ROW_NUMBER() or RANK() partitioned by device group and ordered by total views descending. Finally, filter to the top 3 hours per group, ensuring ties are handled appropriately.

Pro tip: Clarify whether ties should be included (use RANK/DENSE_RANK) or exactly 3 rows (use ROW_NUMBER), and mention that hour should be extracted from a timestamp with proper timezone handling.

1. Aggregate views by device group and hour

Write a subquery or CTE that groups the raw event data by device_group and hour of day, summing the view counts. Use EXTRACT(HOUR FROM timestamp) or equivalent.

2. Apply window function to rank hours

In an outer query, use ROW_NUMBER() OVER (PARTITION BY device_group ORDER BY total_views DESC) to assign a rank to each hour within each device group.

3. Filter to top 3 hours per group

Wrap the ranked result in another CTE or subquery and filter WHERE rank <= 3. This yields the top 3 hours by view volume for each device group.

4. Handle ties and edge cases

If ties are possible, consider using RANK() or DENSE_RANK() instead of ROW_NUMBER() to include all tied hours. Also, ensure hours with zero views are handled if needed.

Key Points to Mention

  • Use of window functions (ROW_NUMBER, RANK, DENSE_RANK) with PARTITION BY device_group and ORDER BY total_views DESC.
  • Aggregation step: SUM of views grouped by device_group and hour.
  • Extracting hour from timestamp (e.g., EXTRACT(HOUR FROM event_time)) and considering timezone.
  • Filtering after ranking (e.g., WHERE rank <= 3) to get top 3 per group.
  • Handling ties: ROW_NUMBER gives exactly 3 rows, while RANK/DENSE_RANK may return more if ties.
  • Performance considerations: indexing, partitioning, and avoiding unnecessary sorting.

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

Q3

Write a single query that returns both the count of unique non-NULL content IDs and the count of view events where content_id is NULL.

Product Analytics & MetricsData Modeling
Author's notes

Easiest one of the four.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Use conditional aggregation with COUNT(DISTINCT CASE WHEN content_id IS NOT NULL THEN content_id END) to count unique non-NULL content IDs, and SUM(CASE WHEN content_id IS NULL THEN 1 ELSE 0 END) to count NULL view events. Combine both in a single SELECT statement to return one row with two columns.

Pro tip: Always clarify whether 'view events' means all rows or only those with NULL content_id; if the latter, the second count is simply the number of rows where content_id IS NULL. Also, confirm if the table might have duplicate view events that need deduplication.

1. Understand the requirements

Identify the two metrics: count of unique non-NULL content IDs and count of view events with NULL content_id. Clarify if 'view events' refers to all rows or only those with NULL content_id.

2. Choose the right aggregation functions

For unique non-NULL content IDs, use COUNT(DISTINCT content_id) with a filter or CASE. For NULL view events, use COUNT(*) with a filter or SUM(CASE WHEN content_id IS NULL THEN 1 ELSE 0 END).

3. Write the query with conditional logic

Construct a single SELECT statement using CASE expressions or FILTER clauses (if supported) to compute both counts in one pass over the data.

4. Test and validate

Run the query on a sample dataset to ensure it returns the expected counts. Check edge cases like all NULLs or no NULLs.

5. Explain and optimize

Articulate the logic clearly and mention potential performance considerations, such as indexing on content_id.

Key Points to Mention

  • Use of COUNT(DISTINCT) for unique non-NULL values
  • Handling NULLs explicitly with CASE or FILTER
  • Single query requirement: avoid multiple subqueries if possible
  • Performance implications of COUNT(DISTINCT) on large datasets
  • Clarifying business context: what constitutes a 'view event'?
  • Ensuring correct handling of NULLs in SQL aggregation

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

Q4

For each agent and calendar day, identify the agent's first view event of the day (breaking ties by event_id), then compute the distribution of content types across all agent-days.

Product Analytics & MetricsData ModelingRoot Cause Analysis
Author's notes

This one took me a minute to think through.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Break the problem into two stages: first, use a window function (ROW_NUMBER) partitioned by agent and calendar day, ordered by event timestamp and then event_id, to isolate each agent's first view event per day. Then, aggregate the resulting set by content type to compute the distribution (counts and percentages) across all agent-days.

Pro tip: Always clarify the definition of 'first view event'—whether it's based on event timestamp or ingestion time—and confirm how to handle ties (e.g., event_id ascending). Also, consider whether the distribution should be weighted by agent-days or by unique agents, as this can change the interpretation.

1. Clarify requirements and edge cases

Confirm the definition of 'first view event' (e.g., earliest timestamp, tie-break by event_id), the time zone for calendar day, and whether to include only view events or all events. Ask about handling nulls or duplicate events.

2. Filter and rank events

Filter the events table to only 'view' events. Use a window function like ROW_NUMBER() OVER (PARTITION BY agent_id, DATE(event_timestamp) ORDER BY event_timestamp ASC, event_id ASC) to assign a rank to each event within each agent-day.

3. Select first event per agent-day

Retain only rows where the rank equals 1. This yields one row per agent per calendar day, representing the first view event.

4. Compute distribution of content types

Group the resulting set by content_type and count the number of agent-days. Calculate the percentage of total agent-days for each content type to get the distribution.

5. Validate and present results

Check for anomalies (e.g., missing days, unexpected content types) and ensure the total count matches the number of agent-days. Present the distribution in a clear table or chart, highlighting key insights.

Key Points to Mention

  • Use of window functions (ROW_NUMBER) for deduplication and ranking
  • Partitioning by agent_id and calendar day (DATE_TRUNC or DATE)
  • Tie-breaking logic using event_id when timestamps are identical
  • Definition of 'distribution' as counts and percentages of agent-days
  • Handling of time zones and date boundaries
  • Potential data quality issues: null content types, duplicate events, or missing days

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