ETLintermediate
Slowly Changing Dimensions: ETL Implementation Patterns
Explain how SCD Type 1, Type 2, and Type 3 patterns are actually implemented in an ETL load process, complementing the RPD-side SCD topic.
The RPD exposes whichever SCD pattern the warehouse implements. This is how the load actually implements it.
Type 1 is like erasing and rewriting a whiteboard — the old value is simply gone. Type 2 is like keeping every previous whiteboard photo ever taken, dated and filed away, so you can look up exactly what it said on any past date. Type 3 is like a whiteboard with a small sticky note showing just what was written there before the current text, but nothing further back than that.
Key Concepts
1
Type 1 overwrites. Compare the incoming row against the existing one by natural key; if a tracked
attribute changed, update it in place.
2
UPDATE d_customer SET region = :new_region
WHERE cust_id = :cust_id;3
History is lost, which is the point. Use it for corrections — a misspelled name — where the old value has
no meaning.
4
Type 2 inserts a new version.
1. find the current row by natural key, where CURRENT = 'Y'
2. if a tracked attribute changed:
UPDATE that row: EXP_DATE = today - 1, CURRENT = 'N'
INSERT a new row: a new surrogate key,
EFF_DATE = today,
EXP_DATE = 9999-12-31,
CURRENT = 'Y'5
SK CUST_ID REGION EFF_DATE EXP_DATE CURRENT
501 C100 North 2020-01-01 2023-06-30 N
847 C100 South 2023-07-01 9999-12-31 Y6
Which attributes are tracked is a business decision, not a technical one. Tracking every column means a
new row whenever a phone number changes, and the dimension grows for no analytical benefit.
7
Tracking only the attributes people slice by — region, segment, grade — keeps it useful.
8
Type 3 keeps the previous value in a column.
CURRENT_REGION PREVIOUS_REGION9
One step of history, fixed. It answers "compare under the old structure and the new" and nothing more. Rare,
and occasionally exactly right for a reorganisation.
10
What the fact load must then do. With Type 2, the fact's foreign key must be the surrogate key that was
current when the transaction happened:
11
lookup: WHERE cust_id = :id
AND :txn_date BETWEEN eff_date AND exp_date12
Not WHERE current = 'Y'. Getting this wrong is the standard defect: every historical fact points at
today's version, so all history is restated under the current structure and the Type 2 dimension was built
for nothing.
WHERE current = 'Y'
13
Late-arriving dimensions are the edge case worth naming: a fact arrives for a customer the dimension has
not yet loaded. Either reject it, or insert a placeholder row to be updated later — and decide which,
because the default is usually a silent failed lookup.
14
What the interviewer is probing.1. "Describe type 1, 2 and 3." Probing: the fundamentals. Stalls: "They track history."
Moves up: type 1 overwrites, type 2 adds a new row with validity dates and a current flag, type 3
keeps a prior-value column.
15
2. "How does the fact join a type 2 dimension?" Probing: the critical detail. Stalls: "On
the key." Moves up: on the surrogate key assigned at load time, so the fact points at the version
current when the event happened.
16
3. "How do you detect a change efficiently?" Probing: the implementation. Stalls: "Compare
every column." Moves up: a hash of the tracked attributes compared against the current row, which
is one comparison rather than dozens.
17
4. "What is the trap with late-arriving facts?" Probing: the depth. Stalls: "None." *Moves
up:* the dimension version current at the event date must be found, not the current one — which
requires a date-range lookup, not a current-flag lookup.