Skip to main content

💻 Make better budget decisions with Marketing Mix Modelling (MMM) – Learn more >

25.07.2025: Blog series 1

How dbt Can Revolutionize Your Marketing Data Stack


HMA Team Giorgio Frisenda 1b90ede9
Giorgio Frisenda on July 24, 2025

Say Goodbye to Complex SQL with cleaner dbt Data Modelling
An article for BI managers and specialists, data analysts, analytics engineers and marketing managers

In today’s fast-moving digital landscape, marketing and advertising teams are expected to make data-driven decisions at every turn, from optimizing campaign performance to fine-tuning customer journeys in real time. Yet the reality is often more chaotic: data lives across siloed platforms, naming conventions are inconsistent, and the meaning of metrics such as attribution or engagement can vary wildly depending on the source.

This fragmentation raises a critical question: How can marketing teams trust, scale, and act on their data confidently?

That’s where the modern Marketing Data Stack comes in. By connecting best-in-class tools across the entire data pipeline – from ingestion to transformation to visualization – it enables scalable, automated analytics that work for marketers.

Hopmann Modern Data Stack with dbt

At the center of this stack is a powerful transformation tool: dbt (data build tool). While ingestion and storage are increasingly standardized, the transformation layer is where the real strategic value is unlocked – especially in marketing, where agility, consistency, and transparency are everything.

For readers new to dbt, or those who just feel like a knowledge refresh, the dbt Fundamentals course offers a helpful introduction. Or check out our HMA Academy dbt training if you want to go deeper.

This series of blogposts compares a traditional Snowflake-only workflow with a more modern approach using dbt (data build tool) alongside Snowflake. We’ll walk through three core advantages of dbt that make it a powerful enabler of clean, reliable, and scalable marketing data pipelines.

Transforming raw marketing data into usable insights is rarely straightforward. Data from ad platforms, CRM systems, and analytics tools can be messy, with inconsistent formats, varying metric definitions, and custom logic like attribution models that constantly evolve.

Traditionally, transforming this data requires using multiple types of SQL across complex stored procedures:

• DDL (Data Definition Language): defines and manages tables (e.g., CREATE TABLE)
• DML (Data Manipulation Language): modifies records (e.g., INSERT INTO, MERGE)
• DQL (Data Query Language): retrieves data (e.g., SELECT)

These workflows are difficult to maintain, hard to debug and often disconnected from the business logic marketers actually care about.

dbt dramatically simplifies this process by using only one SQL command: SELECT. Instead of managing data with procedural code, you write declarative SQL models that describe what you want, and dbt handles the rest – including table creation, updates, and scheduling.

Let’s look at a common example from marketing analytics: incremental data loads. Campaign or engagement data (like ad impressions, clicks, or conversions) often needs to be updated daily, but reloading the entire dataset is inefficient.

Traditionally, incremental updates require complex MERGE logic in a stored procedure (below a reduced SQL version):

Hopmann MERGE logic
# This is a simplified version, production logic may include more error handling and logging.

CREATE OR REPLACE PROCEDURE update_ facebook_campaign_metrics()
RETURNS STRING
LANGUAGE SQL
AS
$$
BEGIN
  MERGE INTO db.intermediate.facebook_campaigns AS target
  USING (
    SELECT * FROM db.raw.facebook_ads
    WHERE updated_at > (
      SELECT MAX(updated_at) 
FROM db.raw.facebook_ads
    )
  ) AS source
  ON target.campaign_id = source.campaign_id
     AND target.date = source.date
WHEN MATCHED THEN UPDATE SET
    campaign_name     = source.campaign_name,
    url	          = source.url,
    total_cost        = source.cost,
    total_impressions = source.impressions,
    total_clicks      = source.link_clicks,
    total_conversions = source.conversions,
    total_reach       = source.reach,
    updated_at	    = source.updated_at

  WHEN NOT MATCHED THEN INSERT (
    campaign_id,
    campaign_name,
    date,
    url,
    total_cost,
    total_impressions,
    total_clicks,
    total_conversions,
    total_reach,
    updated_at
  )
  VALUES (
    source.campaign_id,
    source.campaign_name,
    source.date,
    source.url,
    source.cost,
    source.impressions,
    source.link_clicks,
    source.conversions,
    source.reach,
    source.updated_at
  );  
RETURN 'Success';

In dbt, the same logic is reduced to a clean and readable SQL model:

Hopmann Readable SQL model in dbt
{{ config(
    materialized='incremental',
    unique_key=['campaign_id', 'date']
) }}

SELECT
    campaign_id,
    campaign_name,
    date,
    url,
    total_cost,
    total_impressions,
    total_clicks,
    total_conversions,
    total_reach,
    updated_at
FROM {{ source('raw', 'facebook_ads') }}

# Ensure that only new rows are appended to the table
{% if is_incremental() %}
WHERE updated_at > (
    SELECT MAX(updated_at) FROM {{ this }}
)
{% endif %}

By simplifying complex transformations and making SQL workflows cleaner and easier to maintain, dbt empowers marketing teams to spend less time debugging code and more time acting on trustworthy data.