CodeRigor

LESSON

Reconcile totals and calculate a weighted average

Aggregate the selected order population, keep empty sums explicit and divide total cents by the correct total order count.

A chart is easier to trust when its headline totals can be rebuilt from the accepted order rows. Use the same eligibility, date and dimension filters for count, sum and average.

For the default fixture, five completed orders contribute 5,750 net cents. Their average net value is 1,150 cents. The dataset also includes fractional-average cases so an accidental integer division cannot pass unnoticed.

A ratio has one shared population
start / 3
The same eligible order rows feed the net-value numerator and completed-order denominator. Divide their totals once.
A ratio has one shared population
The same eligible order rows feed the net-value numerator and completed-order denominator. Divide their totals once.

COUNT(*) includes zero-value orders. SUM over no rows returns NULL, while COUNT returns zero. The report chooses zero for an empty money total and NULL for an average with no orders. Those choices mean different things.

Force real division in SQLite with a real-valued numerator such as 1.0*SUM(...). Use NULLIF on the denominator so an empty population remains explicitly undefined.

SQL
WITH input_orders(net_cents) AS (VALUES(100),(101),(0))
SELECT COUNT(*) AS completed_orders, SUM(net_cents) AS net_sales_cents,
       1.0*SUM(net_cents)/NULLIF(COUNT(*),0) AS avg_net_cents
FROM input_orders;

Do not average averages without weights. A day with one order and a day with nine orders should not receive equal weight in an overall per-order average. Retain the sum and count, combine them, then divide once.

Reconcile in both directions: the order rows sum to the KPI, and the per-day or per-channel groups sum to that same total. This works because every order belongs to one date and one channel. Overlapping categories or many-to-many membership would need another explicit allocation/counting policy.

Keep integer cents for totals. The average can be fractional cents as an analytical ratio; the display rounds currency separately. Neither display rounding nor chart scaling should change the underlying reconciled values.

Averages need weights
start / 3
A small and large group contribute their sums and counts. The combined average uses the combined denominator, rather than the number of groups.
Averages need weights
A small and large group contribute their sums and counts. The combined average uses the combined denominator, rather than the number of groups.
SQL
WITH daily(net_cents,orders) AS (VALUES(100,1),(9000,9))
SELECT 1.0*SUM(net_cents)/SUM(orders) AS weighted,
       AVG(1.0*net_cents/orders) AS unweighted
FROM daily;

Write the one-row aggregate. Test an empty population, actual zero-value orders, negative adjustments and a fractional result. Reconcile it with the previous lesson’s eligible order rows.

Next we build that trustworthy order grain from raw one-to-many line and refund relationships.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Optional overview of what the later Power BI branch adds. The core SQL/browser lab here uses its own original fixtures and requires no Power BI installation.