← CVS Health Interview Insights

CVS Health·Data Scientist·Technical Phone Screen·Intermediate

Intermediate
Jul 2026

Summary

SQL-heavy technical screen for a Data Scientist role at CVS Health. Three interconnected queries on a healthcare claims schema, each building on the last. The kind of interview where you realize mid-question that the join order you chose two minutes ago is going to cause you pain.

Questions Asked (3)

Q1

Using a schema with member, claim, and geography tables, write a query to return the 2020 sum of paid_amt grouped by age_band across all states. Age bands with zero 2020 spend should still appear as 0.00, and rows with NULL paid_amt should be excluded.

Data ModelingProduct Analytics & Metrics
Author's notes

The trick here is join order.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the schema relationships and the definition of age_band and geography. Then, build a query that aggregates paid_amt for 2020 by age_band, ensuring all age_bands are included even if they have no claims in 2020, and exclude NULL paid_amt. Use a LEFT JOIN from a distinct list of age_bands to the aggregated claims, and filter for 2020 claims while preserving age_bands with zero spend.

Pro tip: Mention that you would validate the results by checking for unexpected NULLs or missing age_bands, and consider performance implications of joining large tables. Also, clarify whether 'across all states' means summing over all states or grouping by state as well—typically it means summing over all states, but confirm to avoid misinterpretation.

1. Clarify schema and requirements

Ask about the structure of member, claim, and geography tables, and confirm that age_band is derived from member demographics. Ensure that 'across all states' means aggregating over all states without grouping by state.

2. Identify all age bands

Get a distinct list of age_band values from the member table (or a reference table) to ensure all bands appear in the output, even those with no claims in 2020.

3. Aggregate 2020 paid amounts

Filter claims to the year 2020, exclude rows where paid_amt is NULL, and sum paid_amt grouped by age_band. Join member to claim to get age_band.

4. Combine to include zero-spend bands

LEFT JOIN the distinct age_bands to the aggregated sums, replacing NULL sums with 0.00. Ensure the final output has one row per age_band with the total 2020 paid amount.

5. Validate and format

Check that all age_bands are present, NULLs are excluded, and the sum is formatted to two decimal places. Consider edge cases like age_bands with no members.

Key Points to Mention

  • Use of LEFT JOIN to include all age_bands even with zero spend
  • Filtering claims for year 2020 using a date condition (e.g., EXTRACT(YEAR FROM claim_date) = 2020)
  • Excluding NULL paid_amt with a WHERE clause or by using SUM which ignores NULLs but ensure no NULL rows are counted
  • Grouping by age_band and summing paid_amt
  • Handling of zero spend by using COALESCE or IFNULL to display 0.00
  • Consideration of performance: indexing on date and join keys, and potential use of subqueries or CTEs for clarity

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

Q2

Extend the previous query to compute each age band's percentage share of the total 2020 paid amount. Output should be 0 to 100 with two decimal places, and the query must handle division by zero safely.

Data ModelingProduct Analytics & Metrics
Author's notes

Wrapping the denominator in NULLIF felt almost too easy once I remembered it existed.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Build on the previous query by wrapping it in a CTE or subquery that computes the total 2020 paid amount across all age bands, then join or cross-join that total back to each age band's sum. Calculate the percentage as (band_sum / total_sum) * 100, using a CASE statement or NULLIF to avoid division by zero, and round to two decimal places. Ensure the output is between 0 and 100 by handling edge cases like negative amounts or totals of zero.

Pro tip: In healthcare analytics, paid amounts can be negative due to reversals or adjustments, so consider whether to use absolute values or net amounts; also, explicitly state that you're using NULLIF or CASE to handle division by zero, as this shows attention to data quality and production readiness.

1. Aggregate per age band

Compute the sum of paid amounts for each age band for the year 2020, ensuring you filter correctly and group by age band.

2. Compute total paid amount

Calculate the total paid amount across all age bands for 2020, either as a separate CTE or a window function like SUM() OVER ().

3. Calculate percentage share

For each age band, divide its sum by the total sum and multiply by 100, using NULLIF or a CASE statement to return 0 when the total is zero.

4. Format and round

Round the result to two decimal places using ROUND(..., 2) and ensure the output is between 0 and 100, possibly clamping if necessary.

5. Validate and present

Check that percentages sum to 100 (or close due to rounding) and that no division errors occur; present the final query with clear column aliases.

Key Points to Mention

  • Use of NULLIF or CASE to handle division by zero safely
  • Rounding to two decimal places with ROUND function
  • Ensuring percentage is between 0 and 100, considering negative paid amounts
  • Using CTEs or window functions for readability and performance
  • Filtering for the year 2020 correctly (e.g., date_part or year function)
  • Validating that percentages sum to 100 (or explain rounding discrepancies)

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

Q3

For Georgia members only, compute 2019 and 2020 paid totals and the year-over-year absolute and percentage change for the 44-65 and 65+ age bands. Members must actually reside in Georgia; claims from non-GA members should be excluded even if the claim data could be linked.

Data ModelingProduct Analytics & MetricsRoot Cause Analysis
Author's notes

This one has a few landmines.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the data sources and definitions: identify the member and claims tables, confirm how to determine Georgia residency (e.g., state field in member address), and define the age bands based on age at the time of service or a fixed reference date. Then write a query that joins claims to members, filters for Georgia residents, groups by year and age band, and computes the totals and year-over-year changes. Finally, validate the results by checking for data quality issues and ensuring the age bands are mutually exclusive and cover the required ranges.

Pro tip: Pay attention to the age calculation: use the member's age as of the claim date or a consistent reference date (e.g., January 1 of the claim year) to avoid misclassification, especially for members who age into a new band during the year. Also, explicitly confirm whether 'paid totals' means allowed amount, paid amount, or member responsibility, as this can significantly affect the results.

1. Clarify Requirements and Definitions

Confirm the definitions of 'paid totals' (e.g., paid amount, allowed amount), the age bands (44-65 and 65+), and how to determine Georgia residency (e.g., member's state at the time of claim). Ask about any exclusions or data quality filters.

2. Identify and Join Relevant Tables

Locate the member and claims tables. Join claims to members on member ID, ensuring that only members with a Georgia address are included. Be careful to exclude non-GA members even if their claims could be linked.

3. Calculate Age and Assign Age Bands

Compute each member's age at the time of service (or a consistent reference date) and assign them to the appropriate age band (44-65 or 65+). Ensure the bands are mutually exclusive and cover the required ranges.

4. Aggregate Paid Totals by Year and Age Band

Filter claims for years 2019 and 2020. Group by year and age band, and sum the paid amounts to get the total paid for each combination.

5. Compute Year-over-Year Changes

For each age band, calculate the absolute change (2020 total minus 2019 total) and the percentage change ((2020-2019)/2019 * 100). Handle cases where the 2019 total is zero to avoid division errors.

Key Points to Mention

  • Georgia residency filter: Use the member's state of residence, not the claim's place of service, and exclude non-GA members even if claims are linkable.
  • Age calculation: Determine age at the time of service or a consistent reference date (e.g., January 1 of the claim year) to correctly assign age bands.
  • Paid totals definition: Clarify whether 'paid' refers to the amount paid by the insurer, allowed amount, or total claim cost, as this impacts the calculation.
  • Year-over-year metrics: Compute both absolute change and percentage change, and handle potential division by zero when the 2019 total is zero.
  • Data quality checks: Validate that age bands are mutually exclusive, check for missing or invalid state values, and ensure claims are only from the specified years.
  • SQL implementation: Use joins, WHERE clauses for filtering, CASE statements for age bands, and GROUP BY with aggregation functions to compute totals.

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