Medicare Advantage, Part D, Medicaid

MA pbp sas schema

medicare_silver.pbp_sas_schema·partial·silver·annual
Rows
N/A
Columns
17
History
2001 (report_year; effective_period_start 2001-01-01) to 2026 (report_year; effective_period_start 2026-01-01)
Card
yesgrain, traps, filters
Typed tools
0

What it is

  1. 1A schema/data-dictionary (metadata) table for CMS Medicare Advantage / Part D Plan Benefit Package (PBP) Public Use Files.
  2. 2Each row defines ONE column in ONE source PBP PUF table for ONE annual release/quarterly vintage: its name, SAS type (CHAR/NUM), byte length, and ordinal position.
  3. 3It is the layout key used to parse and interpret the actual pbp_* benefit tables (e.g. pbp_b16_dental, pbp_mrx_tier, pbp_b13_other_services) that carry the real MA/Part-D plan cost-sharing values.
  4. 4It contains NO benefit/cost values itself — it is metadata describing the structure of the cost data.

Grain

KeyGrain
report_yearquartertable_namecolumn_name
  1. 1One row per (report_year, quarter, source PBP table, column) — i.e. one column-definition per table per release vintage.
  2. 2Verified: (report_year, quarter, table_name, column_name) yields exactly 80,409 distinct combinations = 80,409 rows (no duplication). column_position is interchangeable with column_name as the 4th key (1:1 within group, 0 violations).

How to read it

  1. 1To parse a PBP benefit PUF, fetch its column layout for a given year: SELECT column_position, column_name, column_type, column_length FROM medicare_silver.pbp_sas_schema WHERE table_name='pbp_b16_dental' AND report_year=2023 ORDER BY quarter, column_position.
  2. 2This returns the exact ordered field list (e.g. pbp_a_hnumber CHAR(5) at pos 1, pbp_b16a_bendesc_amo_oe CHAR(1) ...) so you can correctly read/interpret the dental cost-sharing columns in the actual pbp_b16_dental benefit table.
  3. 3Answers: 'what columns, in what order, of what type/width does this PBP table have for this benefit year?'

Traps

  1. 1This is a DATA DICTIONARY, not data. It contains zero benefit/cost values — only column layouts. To get actual MA/Part-D plan cost-sharing you must query the described pbp_* benefit tables; use this table to know which column is which (name, position, CHAR/NUM type, length).
  2. 2Minimal grain needs all four of (report_year, quarter, table_name, column_name); none alone is a key. column_name is NOT globally unique (header fields like pbp_a_hnumber/bid_id/segment_id/version repeat across 33-46 tables), and table_name+column_name without (year,quarter) collapses ~80k rows to ~41k. quarter is load-bearing.
  3. 3table_name aliasing: the same logical PBP section appears under two naming schemes across years — older short names with a populated input_filename (pbp_b13, pbp_b16, planarea.txt) and newer descriptive names with NULL input_filename (pbp_b13_other_services, pbp_b16_dental, planarea). A naive GROUP BY table_name double-counts the same section.
  4. 4NOT a snapshot/is_current table — there is no is_current column and no dedup is needed. The two ingestion batches (asserted_at 2026-05-15 / parse_revision 1, and 2026-05-20 / parse_revision 2) are disjoint on the grain key (0 overlap); the older batch holds 2001-2026 annual/Q1 baselines, the newer holds 2018-2024 quarterly reissues. Use all rows.
  5. 5input_filename is NULL for 66,562 of 80,409 rows (~83%) — do not treat it as an identity or join key. Use table_name (with the aliasing caveat) instead.
  6. 6cms_vintage_sequence is a per-year release ORDINAL, not the quarter and not a snapshot version — Q1 rows scatter across vintage 1/2/4. observed_period, effective_period_start, and effective_period_end are all 1:1 redundant derivations of report_year (calendar-year benefit period).
  7. 7History is lopsided: 2001-2017 carry only ~8 coarse tables/year (the single annual file, quarter=1); coverage explodes from 2018 (33-39 tables/year) with quarterly reissues. 2025-2026 are partial (11 tables). Don't expect a given pbp_* table's layout to exist in early years.

Columns (17)

ColumnTypeMeaning
table_namestringName of the source PBP PUF table this column belongs to (e.g. pbp_b16_dental, pbp_section_a, pbp_mrx_tier, planarea). 46+ logical tables. GOTCHA: same logical table appears under TWO naming conventions across history — older short names (pbp_b13, planarea.txt) vs newer descriptive names (pbp_b13_other_services, planarea); treat as the same table.
report_yearintCMS PBP contract/benefit year (2001-2026). The primary time dimension; one annual PUF release per year (with quarterly reissues from 2018+).
quarterintQuarter (1-4) of the release vintage within report_year. Part of the grain: 25,322 year/table/column groups span >1 quarter. Pre-2018 years are quarter=1 only (single annual file); 2018+ have Q1-Q4 quarterly reissues of the layout.
column_namestringThe column/field name in the source PBP table (e.g. pbp_b16a_bendesc_amo_oe, pbp_a_hnumber, bid_id). GOTCHA: NOT globally unique — plan-key header fields (pbp_a_hnumber, pbp_a_plan_type, segment_id, bid_id, version) repeat across 33-46 tables since every section carries the same header block.
column_typestringSAS storage type. Only two values: CHAR (text, 44,093 rows) or NUM (numeric, 36,316 rows). Most CHAR fields are length-1 coded Y/N or category flags.
column_lengthintDeclared field byte/character width in the SAS layout (1-51+). For CHAR=character width, for NUM=numeric width. Always non-null. Length-1 CHAR dominates (coded benefit flags).
column_positionint1-based ordinal position of the column within the table layout. 1:1 with column_name inside a (year,quarter,table) group — interchangeable with column_name as the grain key.
input_filenamestringOriginal raw SAS/txt filename inside the CMS zip (e.g. '.\\pbp\\pbp_Section_A.txt'). GOTCHA: NULL for 66,562 of 80,409 rows — the entire 2026-05-20 reload batch plus part of the older batch left it blank. Not a reliable join/identity key; populated mostly on the older short-named table rows.
observed_perioddateDate the schema is observed-for; always Jan 1 of report_year. Redundant — 1:1 derived from report_year.
asserted_atdateDate Vlada ingested/asserted this row. Only two values: 2026-05-15 (13,341 rows, the first/baseline load) and 2026-05-20 (67,068 rows, the quarterly-reissue load). Pairs exactly with parse_revision; marks the ingestion batch, not the CMS publication date.
effective_period_startdateStart of the benefit year the layout applies to; Jan 1 of report_year. The profiler's temporal column. Redundant with report_year.
effective_period_enddateEnd of the benefit year; Dec 31 of report_year. Redundant with report_year (calendar-year benefit period).
cms_vintage_sequenceintPer-year CMS release ordinal: 1=first/annual load, 2=Q2 reissue, 3=Q3, 4=Q4. GOTCHA: correlates with but is NOT equal to quarter — Q1 rows appear under vintage 1, 2, AND 4 across different years. It counts the Nth release CMS issued within a report_year.
parse_revisionintParser/ingestion revision: 1 (13,341 rows, years 2001-2026, the annual/Q1 baseline) or 2 (67,068 rows, years 2018-2024 only, the quarterly reissues). Pairs 1:1 with asserted_at. The two revisions are DISJOINT on grain (0 overlapping keys) — together they form the full unique set; this is NOT a versioned/snapshot table.
parser_artifact_hashstringSHA-256 of the parser artifact that produced this layout. 40 distinct values = one per (year x quarter) source release. Provenance only.
source_urlstringCMS download URL of the PBP PUF zip this layout came from (e.g. .../pbp-benefits-2009.zip). Always non-null. 40 distinct = one zip per release. Lineage/provenance.
sha256_content_hashstringSHA-256 content hash of the downloaded source zip. Always non-null. 40 distinct = one per release; identifies the exact source file version for provenance/dedup.

Query it

describe_data_source(source_fqn="medicare_silver.pbp_sas_schema")     # the card, live
query_substrate(sql="SELECT * FROM medicare_silver.pbp_sas_schema WHERE report_year = '<value>' AND quarter = '<value>' AND table_name = '<value>' AND column_name = '<value>' LIMIT 100")
ItemValue
Typed tools that read itnone; raw SQL
Identity keytable_name
Joinhow_to_join(source_fqn="medicare_silver.pbp_sas_schema")
Raw doorAthena (read-only via query_substrate): medicare_silver.pbp_sas_schema
NoteGrain-governed; live in Glue / query_substrate. Source family pbp_benefits.

This page as markdown: /docs-md/data/medicare_silver_pbp_sas_schema.md · every page in one file: /llms-full.txt