Modeling History and Change: The _HX Pattern
Purpose: To understand Epic’s comprehensive approach to tracking data changes over time.
Healthcare’s Audit Trail Imperative
Section titled “Healthcare’s Audit Trail Imperative”In healthcare, knowing not just what data is current but how it changed over time can be critical. Who updated a diagnosis? When was an address changed? What was the patient’s insurance last year? Epic’s _HX
pattern provides complete audit history for critical data elements.
With 23 history tables, Epic tracks changes to everything from problem lists to addresses, medications to insurance coverage.
Anatomy of a History Table
Section titled “Anatomy of a History Table”History tables mirror their parent tables but add crucial temporal tracking:
The key additions in _HX
tables:
- EFF_START_DATE: When this version became active
- EFF_END_DATE: When this version was replaced (NULL = currently active)
- LINE: Tracks multiple historical records
The Active Record Rule
Section titled “The Active Record Rule”A NULL or empty EFF_END_DATE
indicates the currently active record:
This pattern is identical to data warehousing’s Type 2 Slowly Changing Dimension, where:
- New records are added rather than updating existing ones
- Effective dates track the validity period
- The current record has no end date
Point-in-Time Queries
Section titled “Point-in-Time Queries”The real power of _HX
tables is reconstructing data as it existed at any moment:
Common History Tracking Patterns
Section titled “Common History Tracking Patterns”Let’s explore what Epic typically tracks in history tables:
History tables fall into several categories:
- Clinical History: Problem lists, medications, surgical procedures
- Administrative History: Addresses, phone numbers, insurance
- Financial History: Guarantor information, payment arrangements
- Audit History: User updates, system changes
The Audit Trail
Section titled “The Audit Trail”Many _HX
tables include audit columns to track who made changes:
Common audit columns include:
- User who made the change
- Timestamp of the change
- System or interface that triggered the update
History Table Patterns
Section titled “History Table Patterns”Best Practices for History Queries
Section titled “Best Practices for History Queries”1. Always Consider Time Windows
-- Find all addresses for a patient during 2018SELECT * FROM PAT_ADDR_CHNG_HXWHERE PAT_ID = 'Z7004242' AND (EFF_START_DATE < '2019-01-01' AND (EFF_END_DATE >= '2018-01-01' OR EFF_END_DATE IS NULL));
2. Handle NULL End Dates
-- Safe date comparison with NULL handlingWHERE start_date <= target_date AND (end_date > target_date OR end_date IS NULL OR end_date = '')
3. Join to Current Data Carefully
-- Get current data with its historySELECT c.*, h.EFF_START_DATE as current_sinceFROM current_table cJOIN history_table h ON c.ID = h.IDWHERE h.EFF_END_DATE IS NULL;
History vs. Current Tables
Section titled “History vs. Current Tables”Not all data needs history tracking. Epic’s approach is selective:
Key Takeaways
Section titled “Key Takeaways”- The
_HX
suffix identifies history tables that track changes over time - EFF_START_DATE and EFF_END_DATE define when each version was active
- NULL or empty EFF_END_DATE indicates the currently active record
- This pattern implements Type 2 Slowly Changing Dimensions from data warehousing
- 23 history tables track critical clinical, administrative, and financial changes
- Point-in-time queries let you reconstruct data as it existed at any moment
- Not all tables have history tracking—Epic selectively applies it where audit trails matter most