learn-sales-pipeline-analytics-with-phoebe / Analyst session 1 of 6
Learn B2B Sales Pipeline Analytics with Phoebe · Analyst session 1 of 6

The pipeline data model: events, not states

Ask a CRM what stage a deal is in and it answers instantly. Ask it what stage that deal was in six weeks ago and most CRMs cannot, because every update overwrote the field. Every honest number in the rest of the track, conversion by cohort, cycle time, forecast accuracy, needs the past as it was. Tonight: the three tables a pipeline needs, the one that most teams are missing, and the as-of join that rebuilds any week's pipeline from a stage-history log. The log belongs to Kettle & Co's office-tea team and is constructed, so that two deals can go backwards on purpose.

🟢 Analyst Data analysts who build pipeline reporting and forecasts Hands-on in the browser 45 min
0-3 · Welcome 3-18 · Three tables, the overwrite, the as-of join 18-40 · Build-along: rebuild a past week 40-45 · Q&A
Part 0

Where we start

The Analyst track is for the people who build the numbers the Business track reads. Six sessions: tonight, the data model; then conversion done honestly, by cohort; velocity and cycle time, including deals still open; three forecast methods; how to measure a forecast's error; and the forecast honesty bench, where the three methods meet one real quarter. Every widget computes in your browser. The deal timings and outcomes come from real rows of Olist's public B2B funnel; Kettle & Co's stages, amounts and reps are constructed and labelled wherever they appear.

🎫 Clear all three quiz questions to stamp your passport Live = presented in the 45 minutes Self-study = the full depth, after class ★ Build-along = everyone builds it

★ What you walk out with tonight. A three-table pipeline model you can draw on a whiteboard, the as-of join that turns a stage-history log into a weekly snapshot, and a written list of what your own CRM keeps and throws away. Every later session assumes you can rebuild the pipeline as it stood on any past date.

Part 1 · covers the three tables

Three tables, and the one most teams lack

5 min live

A pipeline needs three tables. The opportunity table has one row per deal and holds its current state. The stage-history table has one row per change: which deal, which stage, from when. The snapshot table has one row per deal per week and records where every deal stood. The first is what the CRM shows. The second is what actually happened. The third is derived from the second, and it is what every trend chart needs.

ONE SOURCE, TWO DERIVED TABLES Kettle & Co's log, constructed: 8 deals, 32 events, weeks 0 to 12 OPPORTUNITY one row per deal deal · stage now · amount · rep 8 rows; the past is gone STAGE HISTORY (events) one row per change deal · stage · from week K-102 · Tasting trial · 6 K-102 · Need confirmed · 9 32 rows; the source WEEKLY SNAPSHOT one row per deal per week week · deal · stage that week built by an as-of join: the latest event at or before each week up to 8 x 13 rows latest event per deal Keep the events. Both other tables can be rebuilt from them; neither can rebuild the events.
🔍 Click to zoom - the hatched table in the middle is the only one that remembers, and it is the one most CRMs keep least
LiveWhat each table is for3 min▶

Opportunity. Today's pipeline review. Amount, owner, close date, stage now. It is the table the CRM edits in place, so it can never answer a question about the past.

Stage history. Append-only: a row is added when a deal changes stage, and nothing is ever updated. Columns: deal id, new stage, timestamp, and ideally who changed it. Many CRMs keep some version of this (a field-history or audit log), often with a retention limit or only for fields someone switched on. Find out which before you promise a trend.

Snapshot. Derived. One row per deal per reporting period, with the stage it was in at the end of that period. Conversion by cohort, stage-to-stage timing and forecast accuracy all read from here.

Self-studyIf your CRM keeps no history at all2 min▶

Start a snapshot tonight: a scheduled job that copies the opportunity table, with a date column, once a week. It cannot recover the past, but in a quarter you will have thirteen weeks of evidence. Some CRMs offer a built-in historical trending or snapshot report; it is worth turning on even if you also run your own copy, because it is the vendor's record of what the table said. Re-verify how far back your vendor's history goes before you rely on it.

Real world

The public data has no history either. Olist's public funnel, the real rows behind this track, ships two tables: every lead with its first-contact date and origin, and every won deal with its won date. There is no stage history and no lost deal. That is common in exports: what survives is the start and the happy ending. Every stage you see on Kettle's pages had to be constructed, which is exactly what a team without an event log ends up doing by hand.

Part 2 · covers the overwrite

How the current state erases what happened

5 min live

When a deal moves backwards, the stage field is simply set to the lower stage. When it is lost, it becomes "Lost". The opportunity table then shows a clean end state and nothing of the path. Two of Kettle's eight deals went backwards. Without the event log, nobody can tell that K-102 once reached a tasting trial, or that K-107 sat at Proposal for three weeks.

TWO PATHS, AND WHAT THE OPPORTUNITY TABLE KEEPS x: week 0 to 12 · y: stage 1 (low) to 4 (high) · constructed K-102 trial, week 6 back, week 9 lost in week 12 K-107 Proposal, week 7 back, wk 10 CRM today: Lost CRM today: Tasting trial overwritten The copper segments exist only in the event log. Stall rate and stage reversals cannot be measured without it.
🔍 Click to zoom - the copper steps are the information the opportunity table throws away
LiveThree questions you cannot answer from current state3 min▶

What did the pipeline look like on the first day of the quarter? The forecast was made from that pipeline. To score the forecast later (Analyst session 5), you need it frozen as it was.

How long do deals sit in each stage? Needs the entry and exit date of each stage, which only the event log holds. Analyst session 3 uses first contact to won because the public rows have nothing in between.

How often do deals go backwards? A reversal is a real signal: a trial that disappointed, a budget that moved. Current state reports the end and hides the stall.

Self-studyClose dates get overwritten too2 min▶

The expected close date is the field most often edited and least often logged. A deal whose close date moved from June to July to September looks, in the opportunity table, like a September deal with no history. Log close-date changes as events alongside stage changes. Business session 2 calls these deals "pushed out", and you can only count them if the old dates were kept.

Part 3 · covers the as-of join

Rebuild any week from the events

5 min live

The snapshot for week w is, for every deal that exists by then, its most recent event at or before w. That operation is an as-of join, and it is the one piece of SQL every pipeline analyst should be able to write from memory. Get the inequality right (at or before, not before) and the snapshot matches what a person looking at the CRM that week would have seen.

SNAPSHOT AT WEEK 9, DEAL K-107 pick the latest event at or before the snapshot date Contacted Need confirmed Proposal Tasting trial wk 4 wk 5 wk 7 wk 9 wk 10 snapshot not yet happened At week 9 the answer is Proposal. The CRM today says Tasting trial, the week-10 event.
🔍 Click to zoom - the copper event is the one the join picks; the hatched one is invisible from week 9
LiveThe as-of join in SQL4 min▶

Most warehouses can do this with a window function. Rank each deal's events at or before the snapshot date, newest first, and keep rank 1. Some engines also have a dedicated ASOF JOIN; the window version runs almost everywhere.

★ Snapshot at one dateSELECT deal_id, stage, changed_at FROM ( SELECT e.*, ROW_NUMBER() OVER (PARTITION BY deal_id ORDER BY changed_at DESC) AS rn FROM stage_events e WHERE e.changed_at <= DATE '2018-06-01' -- at or before ) t WHERE rn = 1;

For a weekly snapshot table, cross join the deals with a calendar of week-end dates first, then apply the same rule per week.

Self-studyTwo bugs that hide in the inequality2 min▶

Strictly before. Using < instead of <= drops a change made on the snapshot date itself, so a deal that moved on Monday morning appears one stage lower in Monday's snapshot.

Time zones. A change stamped 23:30 in one time zone is the next day in another. Decide which clock the snapshot uses (usually the sales team's) and convert before comparing. A forecast frozen on the wrong side of midnight is scored against a pipeline nobody saw.

Build-along

Rebuild a past week from the log

★ 22 min · everyone builds

The widget holds Kettle & Co's eight-deal stage-history log and runs the as-of join in your browser every time you move the slider. The right-hand column is what the opportunity table shows today. Work the five steps and write down what the widget prints; the log is constructed, so the lesson is the mechanism, not the counts.

WHAT THE WIDGET DOES WHEN YOU MOVE THE SLIDER snapshot week slider, 0 to 12 as-of join latest event at or before stage-history log stage in week w middle column CRM today fixed: latest event Where the middle and right columns disagree, the opportunity table has overwritten that week.
🔍 Click to zoom - the copper box is the whole technique; everything else is display

Step 1 · Read week 6. The slider starts there. Copy the verdict line and count how many deals sit at Tasting trial.

★ Step 1 · what the widget printsWeek 6: 8 open, 0 won, 0 lost. The CRM today shows 5 open, 1 won, 2 lost. at Tasting trial in week 6: K-101, K-102, K-105

Step 2 · Move to week 9. Four deals now sit at Proposal. Look at K-102: it has dropped back to Need confirmed. The right-hand column says Lost, which was true only from week 12.

★ Step 2 · the week a quarter's forecast would have usedWeek 9: 8 open, 0 won, 0 lost. at Proposal: K-101, K-103, K-105, K-107 K-102: Need confirmed (week 9) | CRM today: Lost

Step 3 · Score week 9's Proposal deals against today. Of the four deals at Proposal in week 9, read their right-hand column. This is the smallest possible stage-to-outcome table, and you just built it from events.

★ Step 3 · four Proposal deals, what became of themK-101 Won K-103 Contract out K-105 Contract out K-107 Tasting trial (went backwards in week 10)

Step 4 · Read the hint line. It lists every backward move the log holds. Write both down; then ask how your own CRM would store each one.

★ Step 4 · the backward movesWent backwards in the log: K-102 (week 9, Tasting trial to Need confirmed); K-107 (week 10, Proposal to Tasting trial).

Step 5 · Write your own model in three lines. For your CRM, name the table or report that plays each role, and mark the role nobody plays yet. That gap is your first data request.

★ Step 5 · your three tablesopportunity (current state): ________________________________ stage history (events): ________________________________ kept since: ________ weekly snapshot (derived): ________________________________ or: start a weekly copy job

Freeze the forecast's pipeline. On the day a quarter's forecast is made, save that day's snapshot with the forecast. Analyst session 5 scores the forecast against what closed, and the score means nothing if the pipeline it was made from has since been edited.

Homework

Before Analyst session 2

30 min
  1. Find your stage history. Locate the field-history or audit table for opportunity stage in your CRM, and note how far back it goes and whether close-date changes are logged too.
  2. Write the as-of join against it for the first day of last quarter, and count deals by stage.
  3. Compare that count with what the opportunity table says today about the same deals. Write down how many changed stage, and how many went backwards.
  4. If there is no history, schedule a weekly snapshot copy today, and note the date it starts. Every later session gets easier from that date on.
Check yourself

Three questions

Clear all three and Analyst session 1 gets stamped in your passport.

1 · Which table can rebuild the other two?

Current state is the latest event per deal; a snapshot is the latest event at or before each week. Neither can rebuild the events.

2 · In week 9, K-102 sat at Need confirmed; the CRM today says Lost. What does a snapshot at week 9 show for K-102?

The as-of join takes the latest event at or before the snapshot date. The week-12 loss had not happened yet.

3 · A stage change is stamped on the snapshot date itself. Your query filters changed_at < snapshot_date. What goes wrong?

"At or before" means <=. A strict inequality silently lags every same-day change.

Sources covered

What this session teaches, and where it came from

✓Olist's public funnel has leads and won deals, no stage history, no lost dealsOlist, "Marketing Funnel by Olist", Kaggle dataset, CC BY-NC-SA 4.0, read at source (both files opened)
◐CRMs keep field history or snapshot reports, with limitsGeneral vendor behaviour; check your own CRM's documentation and retention before relying on it
◐Kettle & Co's eight-deal event log and every snapshot countConstructed and labelled; printed by the widget on this page
✓The as-of join with a window functionStandard SQL; the widget runs the same rule in the browser

Every fact on this page, and its verification tier, is recorded in the course's source map.

Analyst session 1 cheat sheet · pin this

Three tablesOpportunity (now), stage history (events), snapshot (derived per week).
Events are the sourceAppend-only, never updated. The other two are rebuilt from them.
As-of joinLatest event at or before the date: ROW_NUMBER by deal, newest first, keep 1.
<= not <A strict filter drops same-day changes. Fix the clock and time zone too.
Backward movesK-102 and K-107 went back; the opportunity table kept neither.
Freeze the forecast daySave the snapshot the forecast was made from, or it cannot be scored.