Skip to content
codeyourself.
All field guides

A clean table needs a contract. Design useful quality gates.

Define grain, rejected-row reasons and reconciliation before calling a dataset business-ready.

WHAT YOU’LL TAKE AWAY

State grain and field semantics before adding checks.

Retain rejected-row reasons for investigation.

Reconcile input and output populations without double-counting retries.

Give one row a meaning

An original order feed contains an order identifier, customer identifier and amount in integer units. Before selecting a cleaning function, define one output row: one accepted business order. A raw delivery is not necessarily a new order. A retry can repeat an identifier, while a correction can reuse an identifier with changed values.

Write a compact contract. Specify the identifier scope, whether amounts can be zero, the representation of missing values, and the customer relationship. A column named amount does not tell a reader whether it stores major currency units, minor units or a quantity. Those meanings belong in the contract.

Make rejection explainable

Consider these independent example arrivals:

OrderCustomer known?Amount unitsDecision
o-11yes0Accept if zero is permitted
o-12no80Reject missing relationship
o-13no-5Reject invalid amount under an amount-first rule
o-14yesNULLReject missing amount

An order can violate several rules at once. Decide whether the output contains every violation or one prioritized reason. Those are different grains. If a rejected order has two violation rows, summing violation rows will overstate the number of rejected orders.

Reconcile the populations

Keep separate counts for raw arrivals, distinct identifiers, accepted business records and rejected business records. These numbers need not be equal. Retries increase arrivals without increasing unique orders. A conflict may prevent an identifier from entering the accepted dataset at all.

Define the reconciliation equation at the chosen grain. If each unique identifier must end up accepted or rejected, compare unique inputs with those two mutually exclusive outputs. If some records remain pending reference data, include that explicit third state. Do not hide pending records by silently dropping unmatched joins.

Choose a failure policy deliberately

A diagnostic rule can record violations while letting processing continue. A stricter rule can exclude bad rows. Another policy can stop publication entirely. The right choice depends on the downstream contract and failure impact; a dashboard metric and a financial settlement feed may need different responses.

In a layered pipeline, preserve the original delivery and enough lineage to explain the decision. An intermediate table should make transformations and exceptions inspectable. A business-ready aggregate should have a clear owner, freshness expectation and documented grain. Layer names alone do not create those guarantees.

Treat a rule change as a version change

If zero amounts become invalid tomorrow, the same historical data may produce different results. Record the rule version and decide whether to replay history. Otherwise a changed rejection count may look like a source incident when it actually came from a policy update.

Test missing references, duplicate delivery, conflicting identifiers, empty inputs and a rule boundary. Then explain what the finite fixture suite leaves unproven. Local SQL practice can develop the reasoning; a real pipeline still needs platform-specific operational validation, access controls and a recovery plan.

PAUSE. THINK. EXPLAIN.

Check your understanding

A retry delivers the same event ID three times with identical payloads. Should a business event count automatically increase by three?

Reveal the reasoning

No. Delivery count and unique business-event count are different metrics. The contract must say which grain is intended and how repeated or conflicting identifiers are handled.

Sources & further reading

Created with AI assistance. Examples are educational; verify platform-specific behavior against the linked documentation. Found something unclear? Contact us.

FROM UNDERSTANDING TO DOING

Make the next step a small one.

Create a Free account for six coding challenges and five starter labs. Advanced labs and Architecture Studio are Pro features.

Start free practice
Save your own workPractice with browser fixturesClear Free & Pro accessSQL practice uses local DuckDB fixtures. System-design simulations model assumptions; they do not provision real cloud services.