Tutorial: Migrate Your First Query¶
This tutorial walks you, hands-on, through migrating a typical short-term-desk query from the EWE wrapper view to the generic numera-core view. Plan for about 20 minutes.
By the end you'll have:
- Run an existing query against
fct_ewe_volume_pwr_by_business_case. - Observed that swapping to
fct_volume_pwr_15malone gives diverging output (no BU filter). - Re-applied the EWE BU filter explicitly and confirmed output matches.
- Validated the migration with a side-by-side comparison query.
If you haven't run a basic query yet, do Getting Started first.
Step 1 — Establish a baseline¶
Pick a date with healthy short-term desk activity. Run the existing-style query:
select
delivery_date_utc,
sum(volume_buy_mw) as total_buy_mw,
sum(volume_sell_mw) as total_sell_mw,
count(*) as row_count,
count(distinct (business_case || '|' || grid)) as combos
from fct_ewe_volume_pwr_by_business_case
where delivery_date_utc between '2026-04-01' and '2026-04-07'
group by 1
order by 1
Note the daily total_buy_mw, total_sell_mw, row_count, and combos. These are your migration baseline.
Step 2 — Naive swap (expect divergence)¶
Now run the same shape of query against the generic view, swapping the view name only:
select
delivery_date_utc,
sum(volume_buy_mw) as total_buy_mw,
sum(volume_sell_mw) as total_sell_mw,
count(*) as row_count
from fct_volume_pwr_15m
where delivery_date_utc between '2026-04-01' and '2026-04-07'
group by 1
order by 1
You'll see bigger numbers. The EWE wrapper applies a BU/portfolio filter at the data layer:
external_business_unit IN ('ECC INTD BU', 'NORD POOL AS BU')
OR (external_business_unit = 'EWE TR SHORT TERM BU'
AND external_portfolio = 'PWR_ST_PF_Netting')
The generic view doesn't apply this filter — it surfaces all BU activity. To get the baseline back, you have to add the filter yourself.
Step 3 — Re-apply the EWE filter¶
The external_business_unit and external_portfolio columns live on dim_deal_attribute. The generic view exposes dim_deal_attribute_id, so join through it.
with deals_in_scope as (
select dim_deal_attribute_id
from dim_deal_attribute
where external_business_unit in ('ECC INTD BU', 'NORD POOL AS BU')
or (external_business_unit = 'EWE TR SHORT TERM BU'
and external_portfolio = 'PWR_ST_PF_Netting')
)
select
f.delivery_date_utc,
sum(f.volume_buy_mw) as total_buy_mw,
sum(f.volume_sell_mw) as total_sell_mw,
count(*) as row_count,
count(distinct (f.business_case || '|' || f.grid)) as combos
from fct_volume_pwr_15m f
join deals_in_scope d on f.dim_deal_attribute_id = d.dim_deal_attribute_id
where f.delivery_date_utc between '2026-04-01' and '2026-04-07'
group by 1
order by 1
This is Pattern A from the migration how-to.
Daily totals should now match the baseline. Combo counts should match. Row counts may differ slightly because the generic view is at deal-attribute grain (more granular than the EWE wrapper) — see Step 4.
Step 4 — Reconcile the grain difference¶
The EWE wrapper collapses to (business_case, grid, begin_utc). The generic view is at (business_case, grid, dim_deal_attribute_id, begin_utc) — a finer grain. To match the wrapper exactly, aggregate the generic view to the same grain:
with deals_in_scope as (
select dim_deal_attribute_id
from dim_deal_attribute
where external_business_unit in ('ECC INTD BU', 'NORD POOL AS BU')
or (external_business_unit = 'EWE TR SHORT TERM BU'
and external_portfolio = 'PWR_ST_PF_Netting')
),
collapsed as (
select
f.delivery_date_utc,
f.begin_utc,
f.business_case,
f.grid,
sum(f.volume_buy_mw) as volume_buy_mw,
sum(f.volume_sell_mw) as volume_sell_mw
from fct_volume_pwr_15m f
join deals_in_scope d on f.dim_deal_attribute_id = d.dim_deal_attribute_id
where f.delivery_date_utc between '2026-04-01' and '2026-04-07'
group by 1, 2, 3, 4
)
select
delivery_date_utc,
sum(volume_buy_mw) as total_buy_mw,
sum(volume_sell_mw) as total_sell_mw,
count(*) as row_count,
count(distinct (business_case || '|' || grid)) as combos
from collapsed
group by 1
order by 1
Now row_count should match the EWE wrapper too — same combos × same number of periods.
Step 5 — Side-by-side validation¶
Use the validation harness:
with old_q as (
select
delivery_date_utc,
sum(volume_buy_mw) as buy_mw,
sum(volume_sell_mw) as sell_mw,
count(*) as row_count
from fct_ewe_volume_pwr_by_business_case
where delivery_date_utc between '2026-04-01' and '2026-04-07'
group by 1
),
new_q as (
with deals_in_scope as (
select dim_deal_attribute_id
from dim_deal_attribute
where external_business_unit in ('ECC INTD BU', 'NORD POOL AS BU')
or (external_business_unit = 'EWE TR SHORT TERM BU'
and external_portfolio = 'PWR_ST_PF_Netting')
),
collapsed as (
select
f.delivery_date_utc, f.begin_utc, f.business_case, f.grid,
sum(f.volume_buy_mw) as volume_buy_mw,
sum(f.volume_sell_mw) as volume_sell_mw
from fct_volume_pwr_15m f
join deals_in_scope d on f.dim_deal_attribute_id = d.dim_deal_attribute_id
where f.delivery_date_utc between '2026-04-01' and '2026-04-07'
group by 1, 2, 3, 4
)
select
delivery_date_utc,
sum(volume_buy_mw) as buy_mw,
sum(volume_sell_mw) as sell_mw,
count(*) as row_count
from collapsed
group by 1
)
select
coalesce(o.delivery_date_utc, n.delivery_date_utc) as delivery_date_utc,
o.buy_mw as old_buy_mw,
n.buy_mw as new_buy_mw,
o.buy_mw - n.buy_mw as buy_diff,
o.sell_mw as old_sell_mw,
n.sell_mw as new_sell_mw,
o.sell_mw - n.sell_mw as sell_diff,
o.row_count as old_rows,
n.row_count as new_rows
from old_q o
full outer join new_q n using (delivery_date_utc)
order by 1
Expect buy_diff, sell_diff to be 0 (or within floating-point tolerance) on every day. If any row has a non-zero diff, the deal-scope filter doesn't perfectly match the EWE wrapper — check by listing the contributing BU/portfolio combinations on both sides.
Step 6 — Declare it validated¶
Once the harness returns clean, you can confidently retire the EWE-view dependency in that one query. Move to your next query and repeat. The migration how-to has Before/After pairs and reusable filter patterns for every variant — deal grain, floating, controlling unfiltered, quarterly.
What did you learn?¶
- The generic view exposes the same data the EWE wrapper does, just without the BU/portfolio pre-filter.
dim_deal_attribute_idis the join point for deal-attribute filters (portfolio, instrument, BU, …).- The generic view is at a finer grain than the EWE wrapper; aggregate to collapse.
- Validate each migration before retiring the wrapper dependency.
What's next¶
- Migrate from EWE views (how-to) — full mapping table and Patterns A–D
- Join dimensional views — more filter recipes
- EWE vs numera-core layers — why two layers exist