Skip to content

Header/Line Fact Tables

Operational transaction systems often store transactions using a header/line (parent/child) structure: one header row represents the overall transaction, while multiple line rows represent its individual items.

In the dimensional model, the line level is typically the atomic grain. Header-level dimension foreign keys and degenerate dimensions should therefore be carried onto the line-level fact table.

order_idline_iddate_keystore_keycustomer_keyproduct_keyquantitysales_amount
ORD-1001Jan 1Store AAliceLaptop1$1,000
ORD-1002Jan 1Store AAliceMouse1$50

Both rows share the same order-level context, but each represents a distinct order line at the atomic grain.

Allocated Facts

Header/line transactions often contain facts at different grains. For example, a $100 freight charge may apply to the entire order rather than to an individual line.

Storing the header fact on every line would double-count it: a two-line order would appear to have incurred $200 of freight. Instead, where appropriate, the business can define a rule to allocate the header-level fact down to the line level. This allows the allocated measure to be analyzed and aggregated using the same dimensions as the line-level facts without double-counting.

For example, freight can be allocated based on each line's share of the order's sales:

order_idline_idproduct_keysales_amountallocated_freight
ORD-1001Laptop$1,000$95.24
ORD-1002Mouse$50$4.76

The allocation rule should be defined and approved by the business. A separate header-level fact table may still be useful when the header-level data is needed independently or provides query-performance benefits.

NOTE

Allocation is not exclusive to header/line schemas. This pattern generalizes to any coarser-grained fact - such as pushing a monthly warehouse overhead cost down to individual daily shipments - so it can be sliced by more detailed dimensions.

Profit and Loss Fact Tables Using Allocations

A profit and loss fact table extends the allocation concept to provide profitability analysis at the atomic revenue transaction grain.

The basic equation is:

Revenue - Costs = Profit

A true P&L table combines multiple costs originating from different systems at different levels of detail. Some costs arrive already at the line level, while others arrive at the order level (or higher) and require different allocation rules.

For example, consider an order with two items. The product_cost is already known at the line level. However, a $50 shipping charge might be allocated by revenue share, while a $10 warehouse handling fee might be allocated evenly by unit count (1 unit each).

order_idline_idproductrevenueproduct_costallocated_shippingallocated_handlingprofit
ORD-1001Laptop$1,000$600$47.62$5.00$347.38
ORD-1002Mouse$50$30$2.38$5.00$12.62

Now the revenue and all cost components are at the same atomic grain, allowing profit to be analyzed by any dimension (e.g., customer, product, channel, or store).

Because compiling these costs requires pulling from multiple systems and gaining executive approval on various allocation rules, profit and loss fact tables are often implemented after the foundational dimensional models are established.