mdatool
Healthcare Data Dictionary for the Modern Data Stack
LibraryBlogPricing
mdatool
mdatool

The healthcare data dictionary for dbt, Snowflake, Databricks, and BigQuery. 100,000+ ISO-11179 standard terms, free SQL tools, and AI data modeling.

HIPAA-AlignedEnterprise Ready

Tools

  • SQL Linter
  • DDL Converter
  • Bulk Sanitizer
  • Naming Auditor
  • Name Generator
  • AI Data Modeling
  • HCC Calculator
  • Data Model Canvas

Library

  • Glossary
  • Guides
  • Blog

Company

  • About
  • Contact
  • Pricing

Account

  • Sign Up Free
  • Sign In
  • Upgrade to Pro
  • Dashboard

Legal

  • Privacy Policy
  • Terms of Service

© 2026 mdatool. All rights reserved.

Built for healthcare data teams.

HomeBlogRisk AdjustmentHCC Risk Adjustment Data Model: Building Accurate Risk Score Pipelines
Risk Adjustment

HCC Risk Adjustment Data Model: Building Accurate Risk Score Pipelines

A practical guide to designing the Snowflake and BigQuery data models that power CMS-HCC V28 risk adjustment — including RAF score calculation, member-HCC mapping tables, and the data quality checks that prevent audit findings.

mdatool Team·April 29, 2026·13 min read
HCCrisk adjustmentRAF scoreCMS-HCC V28SnowflakeBigQuerydata modeling

What Is HCC Risk Adjustment and Why Does the Data Model Matter?

🧮HCC Calculator

Calculate RAF scores and estimate risk adjustment payments for Medicare Advantage members.

Try it free

Hierarchical Condition Categories (HCC) risk adjustment is the mechanism CMS uses to pay Medicare Advantage plans accurately for the health status of their enrolled members. Each member's Risk Adjustment Factor ([RAF score](/terms/raf-score)) is calculated from their age, sex, dual-eligibility status, and the HCC codes derived from their diagnoses. A member with diabetes plus chronic kidney disease and heart failure carries a higher RAF score — and therefore higher capitation payments — than a healthy 65-year-old.

The data model that supports this process is not a reporting afterthought. It is the backbone of revenue integrity. A pipeline that drops diagnosis codes, miscodes encounter types, or fails to correctly map ICD-10 to HCC under the active model year (currently V28) will produce RAF scores that undercount the true burden of illness in your population — directly reducing capitation revenue and exposing the plan to RADV audit risk.

🔎ICD-10 Search

Search all 70,000+ ICD-10-CM diagnosis codes instantly by description or code prefix.

Try it free

This guide covers the core tables, relationships, SQL patterns, and data quality checks needed to build a production-grade HCC risk adjustment pipeline on Snowflake or BigQuery.


The CMS-HCC V28 Model: What Changed and Why It Matters

CMS transitioned from HCC V24 to HCC V28 starting in payment year 2024, phasing in over three years. V28 restructured the HCC hierarchy, added new condition categories, and recalibrated coefficients across the board. The key operational impact for data engineers:

  • ICD-10 to HCC mappings changed. A diagnosis code that mapped to HCC 18 under V24 may map to a different HCC — or no HCC at all — under V28. Both crosswalk files must be maintained in your reference data layer during the transition.
  • Hierarchies changed. V28 expanded the number of HCC groups. A member who triggers multiple HCCs within a group keeps only the highest-severity one. Your pipeline must apply the correct hierarchy for the payment year being scored.
  • Coefficients changed. V28 coefficients weight chronic conditions differently than V24. Do not reuse V24 RAF score values for V28 payment years.

Store both crosswalk tables as versioned reference data. Tag every RAF score calculation with its model version. Downstream analytics and audit responses depend on knowing which model year produced a given score.


Core Data Model

The HCC risk adjustment model has four core layers: member demographics, diagnosis claims, HCC mapping reference data, and the computed risk score output.

Member Demographics Table

CREATE TABLE risk.member_demographics (
  mbr_id            VARCHAR(50)   NOT NULL,
  plan_id           VARCHAR(20)   NOT NULL,
  dob               DATE          NOT NULL,
  sex_cd            CHAR(1)       NOT NULL,   -- M / F
  dual_elig_cd      VARCHAR(10),              -- FBDE, FIDE, etc.
  esrd_ind          BOOLEAN       DEFAULT FALSE,
  medicaid_ind      BOOLEAN       DEFAULT FALSE,
  enrollment_dt     DATE          NOT NULL,
  disenroll_dt      DATE,
  payment_year      INT           NOT NULL,
  created_dt        TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(),
  PRIMARY KEY (mbr_id, payment_year)
);

While ERwin requires a complex setup for schema generation, you can generate clean DDL in seconds using our free converter.

Convert your first 5 DDLs — No Credit Card Required

Diagnosis Claims Input Table

This table holds the cleaned, deduplicated diagnosis codes that will be evaluated for HCC mapping. Load from professional (837P) and institutional (837I) claims, ensuring encounter type validation before any code reaches this table.

CREATE TABLE risk.dx_claims_input (
  clm_id            VARCHAR(50)   NOT NULL,
  mbr_id            VARCHAR(50)   NOT NULL,
  svc_dt            DATE          NOT NULL,
  dx_cd             VARCHAR(7)    NOT NULL,   -- ICD-10-CM, no decimal
  dx_cd_position    SMALLINT      NOT NULL,   -- 1 = principal
  enc_type_cd       VARCHAR(10)   NOT NULL,   -- INPATIENT, OUTPATIENT, etc.
  prvdr_npi         VARCHAR(10)   NOT NULL,
  payment_year      INT           NOT NULL,
  data_year         INT           NOT NULL,   -- calendar year of service
  PRIMARY KEY (clm_id, dx_cd, dx_cd_position)
);

HCC Reference Crosswalk

CREATE TABLE risk.icd_to_hcc_xwalk (
  dx_cd             VARCHAR(7)    NOT NULL,
  hcc_nbr           SMALLINT      NOT NULL,
  hcc_desc          VARCHAR(255)  NOT NULL,
  model_version     VARCHAR(10)   NOT NULL,   -- 'V24' or 'V28'
  effective_dt      DATE          NOT NULL,
  end_dt            DATE,
  PRIMARY KEY (dx_cd, hcc_nbr, model_version)
);

CREATE TABLE risk.hcc_hierarchy (
  hcc_nbr           SMALLINT      NOT NULL,
  trumped_by_hcc    SMALLINT      NOT NULL,
  model_version     VARCHAR(10)   NOT NULL,
  PRIMARY KEY (hcc_nbr, trumped_by_hcc, model_version)
);

Member-HCC Mapping (output of stage 1)

CREATE TABLE risk.member_hcc_mapping (
  mbr_id            VARCHAR(50)   NOT NULL,
  hcc_nbr           SMALLINT      NOT NULL,
  hcc_desc          VARCHAR(255)  NOT NULL,
  triggering_dx_cd  VARCHAR(7)    NOT NULL,
  svc_dt            DATE          NOT NULL,
  payment_year      INT           NOT NULL,
  model_version     VARCHAR(10)   NOT NULL,
  hierarchy_applied BOOLEAN       DEFAULT FALSE,
  dropped_by_hcc    SMALLINT,
  PRIMARY KEY (mbr_id, hcc_nbr, payment_year, model_version)
);

RAF Score Output

CREATE TABLE risk.member_raf_score (
  mbr_id              VARCHAR(50)   NOT NULL,
  payment_year        INT           NOT NULL,
  model_version       VARCHAR(10)   NOT NULL,
  demo_raf            NUMBER(6,4)   NOT NULL,
  disease_raf         NUMBER(6,4)   NOT NULL,
  total_raf           NUMBER(6,4)   NOT NULL,
  hcc_count           SMALLINT      NOT NULL,
  calculated_dt       TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(),
  PRIMARY KEY (mbr_id, payment_year, model_version)
);

RAF Score Calculation Logic

The demographic RAF component is a lookup against the CMS coefficient table for age band, sex, and enrollment type. The disease component is the sum of HCC coefficients for all HCCs attributed to the member after hierarchy is applied.

-- Step 1: Map diagnoses to HCCs
INSERT INTO risk.member_hcc_mapping
SELECT DISTINCT
    d.mbr_id,
    x.hcc_nbr,
    x.hcc_desc,
    d.dx_cd                     AS triggering_dx_cd,
    MIN(d.svc_dt) OVER (PARTITION BY d.mbr_id, x.hcc_nbr) AS svc_dt,
    d.payment_year,
    x.model_version,
    FALSE                       AS hierarchy_applied,
    NULL                        AS dropped_by_hcc
FROM risk.dx_claims_input d
JOIN risk.icd_to_hcc_xwalk x
    ON  d.dx_cd         = x.dx_cd
    AND d.payment_year  BETWEEN YEAR(x.effective_dt) AND COALESCE(YEAR(x.end_dt), 9999)
    AND x.model_version = 'V28';

-- Step 2: Apply hierarchy — mark lower-severity HCCs as dropped
UPDATE risk.member_hcc_mapping m
SET    hierarchy_applied = TRUE,
       dropped_by_hcc    = h.trumped_by_hcc
FROM   risk.hcc_hierarchy h
WHERE  m.hcc_nbr       = h.hcc_nbr
  AND  m.model_version = h.model_version
  AND  EXISTS (
         SELECT 1 FROM risk.member_hcc_mapping m2
         WHERE  m2.mbr_id        = m.mbr_id
           AND  m2.hcc_nbr       = h.trumped_by_hcc
           AND  m2.payment_year  = m.payment_year
           AND  m2.model_version = m.model_version
       );

-- Step 3: Compute final RAF scores
INSERT INTO risk.member_raf_score
SELECT
    m.mbr_id,
    m.payment_year,
    'V28'                          AS model_version,
    d.demo_raf,
    SUM(c.coefficient)             AS disease_raf,
    d.demo_raf + SUM(c.coefficient) AS total_raf,
    COUNT(DISTINCT m.hcc_nbr)      AS hcc_count,
    CURRENT_TIMESTAMP()
FROM risk.member_hcc_mapping m
JOIN risk.hcc_coefficients c
    ON  m.hcc_nbr      = c.hcc_nbr
    AND m.model_version= c.model_version
    AND m.payment_year = c.payment_year
JOIN risk.demo_raf_lookup d
    ON  m.mbr_id = d.mbr_id AND m.payment_year = d.payment_year
WHERE (m.hierarchy_applied = FALSE OR m.dropped_by_hcc IS NULL)
GROUP BY m.mbr_id, m.payment_year, d.demo_raf;

Critical Data Quality Checks

RADV audits scrutinize whether each HCC attributed to a member is supported by a valid diagnosis in a face-to-face encounter. Build these gates into your pipeline before any RAF score reaches the submission layer.

-- Flag diagnosis codes not in CMS reference file for the active model year
SELECT dx_cd, COUNT(*) AS occurrences
FROM risk.dx_claims_input
WHERE payment_year = 2025
  AND dx_cd NOT IN (
        SELECT DISTINCT dx_cd FROM risk.icd_to_hcc_xwalk
        WHERE model_version = 'V28'
      )
GROUP BY dx_cd
ORDER BY occurrences DESC;

-- Flag members whose RAF score dropped more than 10% year-over-year
SELECT
    c.mbr_id,
    p.total_raf  AS prior_year_raf,
    c.total_raf  AS current_year_raf,
    ROUND((c.total_raf - p.total_raf) / NULLIF(p.total_raf, 0) * 100, 1) AS pct_change
FROM risk.member_raf_score c
JOIN risk.member_raf_score p
    ON c.mbr_id = p.mbr_id AND c.payment_year = p.payment_year + 1
WHERE ABS((c.total_raf - p.total_raf) / NULLIF(p.total_raf, 0)) > 0.10
ORDER BY pct_change;

Frequently Asked Questions

What is the difference between HCC V24 and HCC V28?

CMS-HCC V28 restructured the condition hierarchy compared to V24, added new HCC groups for mental health and substance use disorders, and recalibrated all coefficients. Some ICD-10 codes that mapped to an HCC under V24 do not map to any HCC under V28, and vice versa. During the three-year transition (payment years 2024–2026), plans must maintain both crosswalk tables and blend V24 and V28 scores according to CMS phase-in ratios.

How is a RAF score calculated?

A member's RAF score has two components: a demographic component (based on age band, sex, Medicaid dual-eligibility status, and enrollment type) and a disease component (the sum of CMS-published coefficients for each HCC attributed to the member after hierarchy is applied). The total RAF score multiplies against a base rate to produce the per-member-per-month capitation payment.

What is HCC hierarchy and why does it matter for data pipelines?

The CMS-HCC model groups related conditions into hierarchies where a more severe condition "trumps" a less severe one in the same disease group. If a member has both diabetic retinopathy and uncomplicated diabetes, only the retinopathy HCC contributes to the RAF score. Your pipeline must apply hierarchy logic after mapping diagnoses to HCCs — counting both conditions overstates the RAF score and creates RADV audit exposure.

What encounter types are valid for HCC risk adjustment?

CMS accepts diagnoses from inpatient hospital stays, outpatient hospital encounters, and physician office visits — but only when billed by an acceptable provider type with a valid face-to-face encounter. Telephone visits, nurse-only visits, and certain ancillary provider types are not acceptable. Filter on encounter type code and rendering provider specialty before allowing a diagnosis into your HCC pipeline.

How do I prevent RADV audit findings in my data model?

The most common RADV findings come from four sources: diagnosis codes with no supporting documentation, HCCs attributed from unacceptable encounter types, incorrect ICD-to-HCC crosswalk versions, and hierarchy applied incorrectly. Build automated quality gates that validate encounter type, crosswalk version, and hierarchy application. Store the triggering claim and date of service for every HCC attributed to every member so medical record requests during audit can be fulfilled within CMS timelines.

M

mdatool Team

The mdatool team builds free engineering tools for healthcare data architects, analysts, and engineers working across payer, provider, and life sciences data.

Related Guides

HCC Risk Adjustment

Hierarchical Condition Categories, RAF scores, and Medicare risk adjustment.

Read Guide

EHR Systems

Electronic Health Record systems, data models, and interoperability standards.

Read Guide

Key Terms in This Article

raf scoreHCC flag

Free Tools

Free HCC RAF Score Calculator

Calculate CMS-HCC V28 RAF scores from ICD-10 codes. No account required.

Try it free

Free SQL Linter

Catch SQL bugs, performance issues, and naming violations before production.

Try it free

Ready to improve your data architecture?

Free tools for DDL conversion, SQL analysis, naming standards, and more.

Get Started Free

Get weekly healthcare data engineering tips

Practical guides on data modeling, SQL standards, and healthcare domain conventions — straight to your inbox.

No spam. Unsubscribe any time.

On this page

  • What Is HCC Risk Adjustment and Why Does the Data Model Matter?
  • The CMS-HCC V28 Model: What Changed and Why It Matters
  • Core Data Model
  • Member Demographics Table
  • Diagnosis Claims Input Table
  • HCC Reference Crosswalk
  • Member-HCC Mapping (output of stage 1)
  • RAF Score Output
  • RAF Score Calculation Logic
  • Critical Data Quality Checks
  • Frequently Asked Questions
  • What is the difference between HCC V24 and HCC V28?
  • How is a RAF score calculated?
  • What is HCC hierarchy and why does it matter for data pipelines?
  • What encounter types are valid for HCC risk adjustment?
  • How do I prevent RADV audit findings in my data model?

Share

Share on XShare on LinkedIn

Engineering Tools

Convert DDL, lint SQL, and audit naming conventions — free.

Explore Tools