Modeling a Grouped List: The (ID, GROUP_LINE, VALUE_LINE) Pattern
Purpose: To understand Epic’s elegant solution for nested lists—lists within lists.
When Simple Lists Aren’t Enough
Section titled “When Simple Lists Aren’t Enough”In the previous chapter, you mastered the (ID, LINE)
pattern for simple lists. But what happens when you need to store groups of related items, where each group itself contains multiple values? Enter the (ID, GROUP_LINE, VALUE_LINE)
pattern—Epic’s solution for hierarchical data.
Understanding Nested Structure
Section titled “Understanding Nested Structure”Think of this pattern as a two-level hierarchy:
- Level 1: Groups (identified by GROUP_LINE)
- Level 2: Values within each group (identified by VALUE_LINE)
Let’s examine a real example with patient history review:
Notice how:
- Group 6 represents one review session covering Alcohol, Sexual Activity, Drug Use, and Tobacco
- Group 7 represents another review session covering the same topics
- Each group has multiple VALUE_LINEs (1-4) for different history types
- The same review location can have multiple review sessions
The Pattern Anatomy
Section titled “The Pattern Anatomy”The composite key for these tables is always (ID, GROUP_LINE, VALUE_LINE):
- ID: Links to the parent record
- GROUP_LINE: Identifies which group (1, 2, 3…)
- VALUE_LINE: Identifies the position within the group (1, 2, 3…)
Real-World Applications
Section titled “Real-World Applications”Let’s explore where Epic uses this pattern:
Common use cases include:
- Lab Results: Multiple result sets from different labs, each with multiple components
- Medication Instructions: Multiple sig versions over time, each with multiple instruction lines
- Patient History Reviews: Multiple review sessions, each covering multiple topics
- Immunization Groups: Multiple vaccine series, each with multiple doses
Querying Grouped Lists
Section titled “Querying Grouped Lists”Working with this pattern requires careful attention to the hierarchy:
1. View Complete Groups
2. Preserve Hierarchy in Results
-- Always order by all three levelsSELECT * FROM grouped_tableORDER BY ID, GROUP_LINE, VALUE_LINE;
3. Join at the Appropriate Level
-- Join at group levelSELECT * FROM parent pJOIN child c ON p.ID = c.ID AND p.GROUP_LINE = c.GROUP_LINE;
-- Join at value levelSELECT * FROM parent pJOIN child c ON p.ID = c.ID AND p.GROUP_LINE = c.GROUP_LINE AND p.VALUE_LINE = c.VALUE_LINE;
The Chronicles Connection
Section titled “The Chronicles Connection”This pattern directly maps to Chronicles’ nested “related multiples”—essentially lists within lists. In Chronicles, a single field can contain:
Group 1: - Value 1.1 - Value 1.2Group 2: - Value 2.1 - Value 2.2 - Value 2.3
The ETL process flattens this into rows while preserving the structure through GROUP_LINE and VALUE_LINE.
Pattern Recognition
Section titled “Pattern Recognition”You can identify this pattern by:
- Presence of both
GROUP_LINE
andVALUE_LINE
columns - Primary key includes (ID, GROUP_LINE, VALUE_LINE)
- Both LINE columns are INTEGER type
- Both start at 1 and increment sequentially
Best Practices
Section titled “Best Practices”- Never assume single groups: Even if current data shows only GROUP_LINE = 1, design queries to handle multiple groups
- Aggregate thoughtfully: Decide whether to aggregate at the group or parent level
- Document the hierarchy: When writing queries, comment what each level represents
- Test with complex data: Simple test data may not reveal the pattern’s full complexity
Key Takeaways
Section titled “Key Takeaways”- The
(ID, GROUP_LINE, VALUE_LINE)
pattern models nested lists—groups of related items - 17 tables in Epic use this pattern for complex hierarchical data
- GROUP_LINE identifies groups (1, 2, 3…) while VALUE_LINE identifies items within each group
- The composite key is always (ID, GROUP_LINE, VALUE_LINE)
- This pattern is Chronicles’ answer to nested data structures in a relational model
- Always query and join considering the full hierarchy to maintain data integrity