← Newyorktimes Interview Insights

Newyorktimes·Data Analyst·Technical Phone Screen·Intermediate

Intermediate
May 2026

Summary

SQL-heavy technical screen for a Data Analyst role at the New York Times. Four questions, all around a single page_views table, ranging from basic aggregation to a window function problem that required careful tie-breaking logic. No behavioral stuff at all, which was a bit of a surprise.

Questions Asked (4)

Q1

Given a page_views table, compute the number of distinct content IDs viewed and the total view events for each device group (mobile vs desktop). Also explain whether those two numbers will typically be equal.

Product Analytics & MetricsData Modeling
Author's notes

Pretty straightforward GROUP BY with a CASE to bucket phone and tab together as mobile.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by writing a SQL query that groups by device group and computes COUNT(DISTINCT content_id) and COUNT(*) (or SUM of view events). Then explain that distinct content IDs and total view events are typically not equal because a single content ID can be viewed multiple times by the same or different users on the same device group.

Pro tip: Mention that the ratio of total views to distinct content IDs gives an average views per content metric, which is useful for understanding content popularity and engagement depth.

1. Understand the table schema

Identify the relevant columns: device group (e.g., device_type), content ID (e.g., content_id), and view event identifier (e.g., view_id or timestamp). Clarify that each row represents a view event.

2. Write the aggregation query

Use GROUP BY device group and compute COUNT(DISTINCT content_id) for distinct content IDs and COUNT(*) for total view events. Ensure proper filtering if needed (e.g., date range).

3. Interpret the results

Explain that the two numbers will typically differ because total view events count every view, while distinct content IDs count unique content items. Multiple views of the same content inflate the total view count.

4. Discuss edge cases

Mention scenarios where they could be equal: if each content ID is viewed exactly once per device group, or if the data is deduplicated. Also note that if there are no repeat views, the numbers match.

5. Provide business context

Relate the metrics to product analytics: distinct content IDs indicate content breadth, while total views indicate engagement volume. The ratio can inform content strategy.

Key Points to Mention

  • COUNT(DISTINCT content_id) vs COUNT(*) or SUM(view_count)
  • Grouping by device group (mobile vs desktop)
  • Repeat views cause total views to exceed distinct content IDs
  • The ratio of total views to distinct content IDs as an engagement metric
  • Potential need to handle NULLs or duplicate rows
  • Business implications: content diversity vs popularity

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

Q2

For each device type (phone, tab, desktop), find the top 3 hours of day by view volume. Break ties by preferring the earlier hour.

Product Analytics & MetricsAlgorithms & Data Structures
Author's notes

The ranking part was fine, used ROW_NUMBER with EXTRACT(HOUR FROM viewed_at) and partitioned by device_type.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the data schema and defining 'view volume' and 'hour of day'. Then outline a two-step process: aggregate views by device type and hour, then for each device type sort hours by total views descending and hour ascending, and select the top 3. Finally, discuss efficient implementation using window functions or sorting.

Pro tip: Mention that you would validate the result by checking for ties and ensuring the tie-breaking rule is applied correctly, and consider if the data is large enough to require a distributed approach like Spark.

1. Clarify requirements and data

Ask about the data source, schema (e.g., columns: device_type, timestamp, view_count), and whether 'view volume' means count of views or sum of a metric. Confirm that 'hour of day' is based on a specific timezone.

2. Aggregate views by device and hour

Group the data by device_type and hour of day (extracted from timestamp), summing the view volume. This yields total views per device per hour.

3. Rank hours within each device

For each device_type, sort the hours by total views descending, and for ties, by hour ascending. Use a window function like ROW_NUMBER() with ORDER BY total_views DESC, hour ASC.

4. Select top 3 and present results

Filter to rows where rank <= 3 for each device_type. Present the results clearly, perhaps as a table with device_type, hour, and total views.

5. Discuss scalability and edge cases

Mention how to handle large datasets (e.g., using partitioning in Spark or indexing in SQL) and edge cases like missing hours or devices with fewer than 3 hours of data.

Key Points to Mention

  • Definition of 'view volume' (e.g., count of views or sum of a metric)
  • Handling ties by preferring earlier hour (use secondary sort ascending on hour)
  • Use of window functions (ROW_NUMBER, RANK) or sorting for top-N per group
  • Efficiency considerations for large datasets (partitioning, indexing)
  • Validation of results (e.g., checking ties, ensuring correct tie-breaking)
  • Potential need to handle timezone or hour extraction from timestamps

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

Q3

From the same table, return two numbers: the count of distinct non-null content IDs ever viewed, and the count of events where content_id is null.

Product Analytics & Metrics
Author's notes

Easiest one of the four.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the table schema and the definition of 'viewed' events. Then write a single SQL query that uses conditional aggregation: COUNT(DISTINCT CASE WHEN content_id IS NOT NULL THEN content_id END) for distinct non-null content IDs, and SUM(CASE WHEN content_id IS NULL THEN 1 ELSE 0 END) for null events. Explain that this approach scans the table once and returns both metrics in one row.

Pro tip: Mention that COUNT(DISTINCT) ignores NULLs by default, so you could simplify the first metric to COUNT(DISTINCT content_id), but explicitly using a CASE statement makes the logic clear and avoids ambiguity. Also note that if the table has duplicate event rows, you may need to deduplicate before counting nulls depending on the definition of 'events'.

1. Clarify the table and event definition

Ask or confirm what table contains the view events and what constitutes a 'viewed' event (e.g., event_type = 'view'). Ensure you understand whether the table has one row per event or per user-content interaction.

2. Identify the two metrics

Break down the request: (1) count of distinct non-null content IDs ever viewed, and (2) count of events where content_id is null. Note that the first is a distinct count and the second is a row count.

3. Write the SQL using conditional aggregation

Use a single SELECT with COUNT(DISTINCT CASE WHEN content_id IS NOT NULL THEN content_id END) and SUM(CASE WHEN content_id IS NULL THEN 1 ELSE 0 END). This avoids multiple table scans and returns both numbers in one row.

4. Consider edge cases and performance

Mention that COUNT(DISTINCT) can be expensive on large tables; if performance is a concern, consider approximate distinct counts or pre-aggregation. Also check if null content_id events should be filtered out for the first metric.

5. Validate and present results

Run the query and sanity-check the numbers: the distinct count should be less than or equal to the total number of non-null events. Present the two numbers clearly, perhaps with a brief interpretation.

Key Points to Mention

  • COUNT(DISTINCT) ignores NULLs by default, so explicit filtering may be redundant but improves clarity.
  • Conditional aggregation (CASE WHEN) allows computing multiple metrics in a single table scan.
  • The difference between counting distinct values and counting rows (events).
  • Handling NULLs in SQL: IS NULL vs. IS NOT NULL, and how they affect aggregate functions.
  • Potential need to filter by event type (e.g., 'view') if the table contains multiple event types.
  • Performance considerations for COUNT(DISTINCT) on large datasets and possible alternatives.

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

Q4

For each agent and each calendar date, identify their first page view of that day using earliest timestamp and smallest view_id as a tiebreaker. Then compute the distribution of first-seen content types across all agent-days, including each type's share of total agent-days per date.

Product Analytics & MetricsData ModelingAlgorithms & Data Structures
Author's notes

This was the one that took real thought.

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() OVER (PARTITION BY agent_id, date ORDER BY timestamp, view_id)) to identify each agent's first page view per day, then aggregate the resulting first-views to compute the distribution of content types across agent-days, including per-date shares. Validate the tiebreaker logic and handle edge cases like missing timestamps or duplicate view_ids.

Pro tip: Explicitly state your tiebreaker logic and how you'd validate it—e.g., checking for duplicate (agent_id, date, timestamp) pairs—because interviewers at The New York Times care about data quality and reproducibility. Also, mention that you'd compute both absolute counts and per-date shares to avoid misleading conclusions from uneven daily volumes.

1. Clarify requirements and assumptions

Confirm the grain (one row per agent per calendar date), the definition of 'first page view' (earliest timestamp, then smallest view_id), and what 'distribution of first-seen content types' means (count and share of agent-days per content type, per date).

2. Deduplicate and rank page views

Use a window function like ROW_NUMBER() OVER (PARTITION BY agent_id, DATE(timestamp) ORDER BY timestamp ASC, view_id ASC) to assign a rank to each page view within each agent-day, ensuring deterministic tiebreaking.

3. Extract first page views

Filter the ranked dataset to keep only rows where rank = 1, yielding one first page view per agent per day.

4. Aggregate content type distribution

Group the first page views by date and content_type to count agent-days, then compute each type's share of total agent-days for that date using a window function or a self-join to the daily total.

5. Validate and present results

Check for anomalies (e.g., dates with zero agent-days, unexpected content types) and present both counts and shares, noting any assumptions or data quality caveats.

Key Points to Mention

  • Use of window functions (ROW_NUMBER) for deterministic ranking with tiebreakers
  • Partitioning by agent_id and calendar date to isolate daily first views
  • Handling of ties: timestamp first, then view_id as a secondary sort key
  • Computing per-date shares by dividing each content type's count by the total agent-days for that date
  • Data quality checks: duplicate timestamps, missing view_ids, or null content types
  • Performance considerations: indexing on (agent_id, date, timestamp, view_id) for large datasets

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