Keep the first project deliberately small
Use two authorized tables: customers and orders. Your output is a customer summary containing order count, total completed-order value, and most recent completed-order date. Define whether customers with no orders should appear and how refunds are handled. Those choices belong in the project brief before they become SQL.
Dbt transforms data using the execution platform configured for your project; it is not a universal replacement for ingestion or orchestration. Choose a supported adapter and follow its current setup requirements. Use a development environment and synthetic or approved sample data. Keep credentials outside version control, and confirm which database and schema your commands will affect.
Establish sources and a readable model structure
Declare the input relations as sources and build staging models that rename fields, cast types, and standardize documented status values. Keep staging transformations straightforward so differences from the original source remain easy to inspect. Avoid adding business aggregations before the raw fields have a stable meaning.
Create a final reporting model that references the staging models using ref rather than hard-coded relation names. This allows dbt to understand model dependencies. Use a left join if the requirement includes customers without completed orders, and decide explicitly whether their totals should be zero or null. Document the row grain in the model description and use names that reflect it.
Write SQL that survives realistic examples
Create a tiny sample with one customer who has two completed orders, one with a canceled order, and one with no orders. Hand-calculate the expected output before running the transformation. Include duplicate source identifiers as a deliberate negative case so you can see whether your assumptions are enforced.
Check aggregation before joining if the relationship could multiply rows. Do not hide duplication with DISTINCT without understanding its cause. Use the sample to verify date handling, refunds, and null behavior. The first model should be simple enough that a reviewer can trace every output value to source records rather than trusting a large query because it compiled.
Attach tests to the assumptions that matter
Add unique and not-null tests to the customer summary key. Test accepted status values where the source contract defines them, and check that order customer references are valid under your business rules. Dbt's documentation describes built-in tests for uniqueness, non-null values, relationships, and accepted values. [1](https://docs.getdbt.com/docs/build/data-tests)
Add a singular test for a project-specific rule, such as a completed order missing its completion timestamp. Write it to return violating records. The dbt recommended-tests guidance emphasizes primary-key tests and checking source assumptions. [2](https://docs.getdbt.com/faqs/Tests/recommended-tests) Prioritize tests that would reveal incorrect reporting rather than attaching the same arbitrary checks to every column.

Run, inspect, and document the project
Run the relevant development commands for your installed dbt version and adapter, then inspect both compiled SQL and resulting tables. Use dbt build when you want the selected resources and associated checks executed in dependency order according to the command's behavior. Read failures rather than repeatedly rerunning until a transient issue disappears.
Document column meanings, source ownership, refresh expectations, and known exclusions. Keep a README with setup instructions, required environment variables, the development target, and a safe example invocation. Capture package and adapter versions so another learner can reproduce the environment. Generated documentation is useful only if the descriptions explain real assumptions instead of repeating column names.
Practice a change and a failed test
Change the definition of completed revenue in a branch and show which models and tests are affected. Review the diff and expected numerical impact before applying it to shared outputs. This teaches why a dependency graph and versioned transformation logic matter more than simply moving SQL into a new folder.
Finally, insert a duplicate key into the development fixture and verify that the test fails. Repair the input, rerun, and reconcile the result with your hand calculation. Stop before adding incremental models or elaborate macros unless the project needs them. A strong starter project demonstrates correct modeling, understandable lineage, and meaningful failure detection with very little machinery.
Sources & further reading
Last editorial review: 27 October 2026. Examples are educational, not live employer data or guaranteed outcomes.


