How does an aggregate fact table differ from a periodic snapshot fact table?
answer
- can you rebuild it by re-summing the detail?
- flows accumulate, levels just exist
- what does a zero row mean in each?
- one is redundant by design, one is not
- derived rollup versus measured state
basics
~20 sAn aggregate fact table is derived — re-summing the atomic transaction rows reproduces it exactly. A periodic snapshot measures state at set intervals, such as month-end balances, which transactions alone cannot reproduce, and its measures are usually semi-additive.
solid answer
~60 sBoth have one row per period per set of dimensions, which is why they get confused, but they are different kinds of table. An **aggregate fact table** is a performance artifact: a summary of an atomic fact table at a coarser grain. Delete it and you lose nothing but speed, because re-running the `GROUP BY` over the detail rebuilds it exactly. A **periodic snapshot fact table** is a first-class fact table in its own right. It records the *state* of something at regular intervals — inventory on hand at each month end, account balance on each closing day, headcount per month. That state is often not derivable from transactions alone: opening balances predate the transaction history, adjustments arrive outside the transaction stream, and the point-in-time value is what the business actually reports on. Its measures are typically semi-additive, adding across product and location but not across time. So the test is: could you rebuild this table by summing the atomic fact? If yes, it is an aggregate. If it measures a level rather than a flow, it is a snapshot.
code
text · 11 linesAGGREGATE (derived from transactions)
month_key product_key units_sold revenue
202403 P100 1200 48000
-- no row for a product that sold nothing in March
-- rebuild: SUM over fact_sales, GROUP BY month, product
PERIODIC SNAPSHOT (measured state)
month_key product_key warehouse_key on_hand_qty
202403 P100 W1 340
202403 P200 W1 0 <- meaningful zero
-- SUM(on_hand_qty) across months is nonsensego deeper
Know that both tables have one row per period but only one of them is a summary. An aggregate is a faster copy of detail you already have; a month-end balance table is measuring something new.
Apply the derivability test out loud — can re-summing the atomic fact reproduce this table? — and connect the answer to additivity: flows sum across time, levels do not.
Show the operational consequence: losing an aggregate is a rerun, losing a snapshot is data loss, and be able to spot a snapshot that someone has mislabelled and is summing across time.
Own the convention that tells consumers which is which — naming, documented summarization rules per measure, and a semantic layer that refuses to sum a level across the time dimension.
## Why the two get confused An aggregate fact table at month grain and a periodic snapshot fact table both look like "one row per month per product per location, with some numbers on it". The shapes are similar; the roles are not, and mixing them up leads to summing something that should never be summed. ## The four fact table types, for orientation Dimensional modelling recognizes four kinds of fact table: - **Transaction** — one row per event as it happens (an order line, a payment, a click). The atomic layer of most warehouses. - **Periodic snapshot** — one row per entity per regular interval, capturing state at that moment (inventory at each month end, balance at each day close). - **Accumulating snapshot** — one row per pipeline instance, updated in place as it passes milestones (an order from placement through shipment to delivery). - **Factless** — rows recording that something happened or was eligible, with no numeric measure (attendance, promotion coverage). An aggregate fact table is not a fifth type. It is a coarser-grained copy of one of these — nearly always of a transaction fact table. ## The distinguishing test: derivable or measured Ask one question: **can this table be reproduced by re-summing the atomic fact table?** A month-by-product sales aggregate can. Every row is `SUM(revenue)` over the order lines in that bucket. It is redundant by design, kept only because reading it is cheaper. A month-end inventory snapshot generally cannot. To derive on-hand quantity from movement transactions you would need a correct opening balance from before the warehouse's earliest transaction, plus every adjustment, shrinkage and correction ever applied — often outside the transaction feed entirely. In practice the snapshot is loaded from the operating system's own balance, because that is the number the business reports. This is why deleting an aggregate is a performance regression while deleting a snapshot is data loss. ## Flows versus levels A second framing that interviewers like: transaction facts and their aggregates measure **flows** — quantities that accumulate over an interval and are fully additive, so summing days into months is meaningful. Periodic snapshots measure **levels** — quantities that exist at an instant. Levels are **semi-additive**: on-hand inventory adds correctly across products and warehouses, but summing January's daily balances yields a number roughly thirty times too large. A snapshot's summarization over time is an ending value or an average, never a sum. ## Density differs, and that matters An aggregate is **sparse**: it has a row only where activity occurred. A product that sold nothing in March simply has no March row, and that is correct — nothing happened. A periodic snapshot is typically **dense**: every product in every warehouse gets a row every period, including the ones with a balance of zero, because "we held none of this on 31 March" is itself a fact the business needs. That density decision is deliberate and makes snapshots grow predictably rather than with activity — and it means a zero row in a snapshot is meaningful, while a missing row in an aggregate is. ## Both can exist over the same process The two are not alternatives. A warehouse can hold a daily inventory snapshot *and* a monthly aggregate of that snapshot — where "aggregate" means the month-end row or the average daily balance, selected rather than summed. The aggregate of a snapshot is still derived; it just uses a summarization rule other than `SUM` over the time dimension. ## Naming keeps them apart Because the shapes are similar, naming does real work. `agg_` or `_summary` prefixes for derived rollups; `snapshot` in the name for state tables; and measure names that state the rule — `ending_balance`, `avg_daily_balance` rather than a bare `balance` on a month-grain row. A month-grain table with a column called `quantity` tells a reader nothing about whether summing it is legitimate. ## What interviewers listen for The derivability test, the flow-versus-level distinction, and semi-additivity. A candidate who says "a monthly balance table is just an aggregate of transactions" has usually never had to explain to finance why the year-to-date balance came out twelve times too high.
- If you delete both tables by accident, what is the difference in recovery?The aggregate is regenerated by re-running its GROUP BY over the atomic fact table, so recovery is a rerun. The snapshot usually cannot be reconstructed — deriving past balances needs an opening position and every adjustment, often unavailable — so it must be restored from backup or reloaded from the source, if the source still holds history at all.
- Why do periodic snapshots normally carry rows for zero balances while aggregates do not?A snapshot answers 'what was the level at this moment', so 'zero on hand' is a real, reportable answer and the table is loaded densely. An aggregate answers 'how much happened in this bucket'; a bucket with no activity has no row, and the absence is the answer. Densifying an aggregate would only add rows nobody asked for.
- Can you build an aggregate over a periodic snapshot fact table?Yes, but the summarization rule is not SUM over time. A monthly rollup of a daily balance snapshot stores the month-end value or an explicitly named average daily balance. Summing daily levels across the month produces a figure roughly thirty times too large.
An aggregate is a monthly total of your bank deposits — recomputable from the transaction list. A periodic snapshot is your balance printed on the last day of each month: a level, not a flow, and adding twelve of them together means nothing.
saying these in an interview costs you the question
- Calling a month-end balance table an aggregate of transactions
- Summing snapshot balances across time periods
- Treating an aggregate as a distinct fourth fact-table type
- Assuming a missing period row means missing data in a snapshot
- Naming a month-grain state column simply 'balance'