skip to content

What does an SCD Type 6 hybrid dimension let an analyst report that Type 2 alone cannot?

level: seniorimportance: should knowfreq 42%

answer

  1. one plus two plus three
  2. versions kept, but something is also overwritten
  3. which column would a sales director want?
  4. the overwrite touches historical rows too
  5. two totals from the same facts

basics

~20 s

An SCD Type 6 dimension carries a current-value column alongside its Type 2 versions, so the same star answers both as-it-was and as-it-is: group by the versioned column for history, or by the current column to roll a member's whole history under today's value.

solid answer

~50 s

Pure Type 2 welds every fact to the attribute value that was in force when it happened, which is correct for "how did the West region perform in 2023" and useless for "show me everything my current West team has ever sold". **Type 6** is the 1+2+3 hybrid: it keeps genuine Type 2 versioning, and adds a **current-value column that is overwritten on every version of that member** whenever the attribute changes — a Type 1 update applied across the member's whole history — often with a Type 3 style prior-value column too. Both columns then sit on every row, so the report author picks the semantics by picking the column: `region` gives as-was totals, `current_region` gives as-is totals over the identical facts. The costs are that each change must update all historical rows for that member, and that two similarly named columns are an invitation to misreport, so naming and documentation carry real weight.

code

text · 6 lines
text
cust_sk | cust_id | region | current_region | is_current
  501   |  4711   | Texas  | Oregon         |     N
  902   |  4711   | Oregon | Oregon         |     Y

-- version 501 keeps its historical truth (Texas)
-- but its current_region was rewritten when the customer moved

go deeper

for a junior

Recall that Type 6 combines Types 1, 2 and 3 on one dimension, so versions are kept and a current-value column is also carried. Know that it lets a report show either the historical or the present-day value.

for a middle

Explain the mechanics precisely: the current-value column is overwritten on every version of that member, not just the newest, which is what makes an as-is rollup a simple GROUP BY on the same facts.

for a senior

Show the operational judgment: the write amplification on every change, the ambiguity of two similar column names in a self-service tool, and the fact that as-is reports are not reproducible over time. Say when a view or semantic-layer measure serves better.

for a principal

Own the semantics as a published contract — which column each standard report uses, how they are named so misuse is unlikely, and where the organisation draws the line between materialising a second view and computing it in the semantic layer.

## Why Type 2 alone is not enough Under Slowly Changing Dimension Type 2, each change inserts a new version row and the fact table stores the surrogate key of the version current at load time. That is exactly what you want for historically faithful reporting: a sale made while a customer lived in Texas stays credited to Texas forever. But it makes a second, equally legitimate question unanswerable by a simple grouping. The Oregon sales director wants the *total lifetime value of the customers she manages today*, including what they bought before they moved into her region. Under pure Type 2 that requires re-deriving each fact's member and looking up its current version — a self-join or a subquery on every report. The business is not asking a strange question; the model just does not surface it. ## The Type 6 construction Type 6 gets its number from 1 + 2 + 3 (and also, conveniently, from 1 × 2 × 3). It layers all three behaviours on one dimension: - **Type 2**, the backbone: a new row per change, so versions exist and facts point at them. - **Type 1**, applied unusually: a second column holds the *current* value of the attribute, and on every change that column is overwritten **on all rows for that member**, historical versions included. - **Type 3**, optionally: a prior-value column for the immediately preceding value, when the business wants a one-step comparison as well. ```text cust_sk | cust_id | region | current_region | is_current 501 | 4711 | Texas | Oregon | N 902 | 4711 | Oregon | Oregon | Y ``` The key observation about that sketch: the retired 2023 version still says `region = 'Texas'` — its historical truth is intact — but its `current_region` has been rewritten to Oregon. Every fact bound to version 501 can now be rolled up either way. ## Two semantics, one query shape ```sql -- as-was: credited where the customer lived at the time SELECT d.region, SUM(f.amount) FROM fact_sales f JOIN dim_customer d ON d.cust_sk = f.cust_sk GROUP BY d.region; -- as-is: the same facts rolled under today's region SELECT d.current_region, SUM(f.amount) FROM fact_sales f JOIN dim_customer d ON d.cust_sk = f.cust_sk GROUP BY d.current_region; ``` Same facts, same join, different totals — and both are right. That is the sentence to say in an interview: Type 6 turns a choice of *semantics* into a choice of *column*, which is something a self-service analyst can make without writing a correlated lookup. ## What it costs **Write amplification on change.** A Type 1 column that must reflect today's value on every historical row means each change touches all of that member's rows, not just the newest. For a dimension with many versions per member this is a materially heavier load step than plain Type 2, and it is the reason some teams push the as-is view into a view or a semantic-layer measure instead of materialising the column. **Ambiguity risk.** Two columns whose names differ by one word, both plausible in a report builder's field list, both returning sensible-looking numbers. There is no error message when someone picks the wrong one — only a different answer. This is a documentation and naming problem before it is a technical one: `region_at_time_of_sale` and `region_current` are much safer than `region` and `current_region`, and the model documentation should state which one each standard report uses. **Reproducibility of the past.** A report run last quarter that grouped by the current-value column will not reproduce today, because that column has since been rewritten. Only the versioned column is stable over time. Consumers who need a frozen number must use the as-was column or snapshot the result. ## When it is the right call Type 6 earns its complexity when *both* views are genuinely and repeatedly required over the same facts — sales territory analysis is the archetype, as is any organisational hierarchy where people ask both "what did this team achieve" and "what have the people now on this team achieved". When only one view is needed, Type 2 alone is simpler and cheaper; when the second view is occasional, a view or a semantic-layer measure that resolves the current version can serve it without carrying the write cost on every load. A final note on vocabulary: some teams describe any Type 2 dimension carrying a current-value column as Type 6 even without a prior-value column, and that usage is common enough to be safe in an interview — but say what the columns actually do rather than leaning on the number, because the number alone does not tell your interviewer whether you understand the write amplification.

  • Why is the Type 1 update in a Type 6 dimension more expensive than an ordinary Type 1 update?
    An ordinary Type 1 update touches one row per member. In a Type 6 dimension the current-value column must be right on every version of that member, so a single change rewrites all of that member's historical rows. For members with many versions this turns a point update into a multi-row rewrite on every load, which is why some teams resolve the as-is view in a view or semantic layer instead.
  • A report grouped by the current-value column produced different totals when re-run three months later. Why?
    Because that column is deliberately rewritten whenever a member's attribute changes, including on historical rows. The as-is view always reflects today's assignments, so it is not reproducible across time by design. Anything that must reproduce exactly should group by the versioned column, which never changes once a version is retired, or be snapshotted when published.
  • When would you deliver the as-is view without materialising a current-value column?
    When the second view is occasional rather than routine. A view or a semantic-layer measure can join each fact's version back to that member's current version at query time, giving the same answer with no extra write cost on every load. You trade a little query complexity and cost for a simpler, cheaper dimension load — a sensible trade when the as-was view carries the bulk of reporting.

saying these in an interview costs you the question

  • Type 6 just means Type 2 with extra columns nobody updates
  • The current-value column is only set on the current row
  • Type 6 removes the need for versioning
  • A report on the current-value column reproduces exactly later
  • Type 6 is a numbered type for combining any two types you like

context