Use CasesAIPostgreSQLMySQL

How to Track Marketing Campaign Performance Directly from Your Database

Every marketing team has the same problem: the numbers that matter most live in your database, not in your dashboards. Your CRM captures leads, your app data...

Marcus Chen· Solutions EngineerMarch 30, 20267 min read

Every marketing team has the same problem: the numbers that matter most live in your database, not in your dashboards. Your CRM captures leads, your app database logs conversions, your billing system records revenue but pulling those three together to answer "did that campaign actually drive paying customers?" means either waiting for a data analyst or wrestling with spreadsheet exports from three different systems.

This article walks through how to track campaign performance directly from your database, including what queries to run, how to build dashboards that stay fresh without manual effort, and how tools like AI for Database make this accessible without writing SQL.

Why Marketing Data Lives in Your Database (Not Your BI Tool)

Marketing platforms like Google Ads, HubSpot, and Mailchimp give you clicks and opens. What they can't tell you is what happened after the click whether that lead became a trial user, whether the trial converted to paid, and whether that customer is still active six months later.

That data lives in your product database. Specifically:

  • Attribution data: UTM parameters stored when a user signs up
  • Conversion events: Rows written when a user completes a key action (upgrade, purchase, activation)
  • Revenue data: Transactions or subscriptions in your billing tables
  • Churn data: Cancellations, downgrades, or inactivity flags
  • When these tables are queryable, you can answer questions that no marketing platform can: "What was the LTV of customers from our Q1 LinkedIn campaign?" or "Which content piece drove the most paying customers in the last 90 days?"

    The Core Queries: What to Run

    Here are the fundamental queries most marketing teams need. These assume a PostgreSQL-style schema adjust table and column names to match yours.

    Campaign-to-Signup Attribution

    SELECT
      utm_source,
      utm_campaign,
      COUNT(*) AS signups
    FROM users
    WHERE created_at >= '2026-01-01'
      AND utm_source IS NOT NULL
    GROUP BY utm_source, utm_campaign
    ORDER BY signups DESC;

    This tells you which campaigns are actually producing sign-ups, not just clicks.

    Signup-to-Paid Conversion by Campaign

    SELECT
      u.utm_campaign,
      COUNT(DISTINCT u.id) AS signups,
      COUNT(DISTINCT s.user_id) AS paid_conversions,
      ROUND(
        COUNT(DISTINCT s.user_id)::numeric / NULLIF(COUNT(DISTINCT u.id), 0) * 100, 1
      ) AS conversion_rate_pct
    FROM users u
    LEFT JOIN subscriptions s
      ON s.user_id = u.id
      AND s.plan != 'free'
      AND s.created_at <= u.created_at + INTERVAL '30 days'
    WHERE u.created_at >= '2026-01-01'
    GROUP BY u.utm_campaign
    ORDER BY conversion_rate_pct DESC;

    This is the query most marketers need but almost never have: which campaign produced the highest-converting leads, not just the most leads.

    Revenue by Campaign (LTV Approximation)

    SELECT
      u.utm_campaign,
      COUNT(DISTINCT u.id) AS customers,
      SUM(t.amount) AS total_revenue,
      ROUND(SUM(t.amount) / NULLIF(COUNT(DISTINCT u.id), 0), 2) AS revenue_per_customer
    FROM users u
    JOIN transactions t ON t.user_id = u.id
    WHERE u.utm_source IS NOT NULL
    GROUP BY u.utm_campaign
    ORDER BY total_revenue DESC;

    This is what you need to justify ad spend: revenue actually attributable to each campaign.

    Building a Live Campaign Dashboard

    Running these queries manually works for one-off analysis. For ongoing tracking, you need a dashboard that refreshes automatically otherwise it just becomes another spreadsheet someone has to maintain.

    The ideal setup:

  • Connect your database (PostgreSQL, MySQL, Supabase, or any other)
  • Define your queries in plain English or SQL
  • Set a refresh schedule daily is usually enough for campaign tracking
  • Share a read-only link with stakeholders who need visibility
  • With AI for Database, you can skip writing the SQL entirely. You ask questions like:

    "Show me paid conversions by UTM campaign for the last 60 days"

    The tool translates that into the correct SQL for your schema, runs it, and displays the result as a chart. You then pin that question to a dashboard that refreshes every morning. No copy-paste. No exports. No waiting on an engineer.

    Setting Up Automated Campaign Alerts

    Beyond dashboards, the most valuable thing you can do is set up alerts for campaign-linked events so you know immediately when something is working (or not working).

    Useful triggers to monitor:

  • Conversion rate drops below threshold: If a campaign's trial-to-paid rate falls under 5%, something changed maybe the landing page, maybe the audience targeting.
  • Daily signup volume from paid channels: If spend is up but signups are flat, that's a real-time signal before your weekly review catches it.
  • High-LTV cohort activation: When users from a specific campaign complete your activation milestone, that's a signal to double down on that channel.
  • A database-level alert for these doesn't require a DBA or stored procedures. You define the condition in plain language, connect it to a Slack channel or email, and the system checks it on your schedule.

    For example, in AI for Database you'd set a workflow like:

    Condition: Daily signups from utm_source = 'google' drops more than 20% vs. 7-day average Action: Send Slack alert to #marketing-ops

    This runs silently in the background. You find out when something changes, not on the Monday morning review call.

    Multi-Touch Attribution from Your Database

    Most teams use last-touch attribution by default (the last campaign before a conversion gets credit). It's simple, but it understates the value of top-of-funnel content.

    If you store multiple UTM events per user for example, a marketing_touches table that logs every session you can do basic multi-touch attribution directly in SQL.

    -- First touch vs last touch comparison
    WITH touches AS (
      SELECT
        user_id,
        utm_campaign,
        touched_at,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY touched_at ASC) AS touch_rank,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY touched_at DESC) AS reverse_rank
      FROM marketing_touches
    )
    SELECT
      t.utm_campaign,
      COUNT(CASE WHEN touch_rank = 1 THEN 1 END) AS first_touch_conversions,
      COUNT(CASE WHEN reverse_rank = 1 THEN 1 END) AS last_touch_conversions
    FROM touches t
    JOIN users u ON u.id = t.user_id
    WHERE u.plan != 'free'
    GROUP BY t.utm_campaign
    ORDER BY first_touch_conversions DESC;

    This tells you which campaigns introduce customers vs. which campaigns close them two very different jobs, and both matter.

    What Most Marketing Teams Get Wrong

    Relying on ad platform attribution. Google Ads will attribute every conversion it can to Google Ads. Your database doesn't have that conflict of interest.

    Measuring clicks and opens, not revenue. A campaign that generates 10,000 clicks but zero paying customers isn't working. Measure what matters.

    Using campaign data that's weeks old. If your only view of campaign performance is a monthly report, you can't make decisions fast enough. Daily or weekly refresh is the minimum for paid campaigns.

    Not controlling for time. Comparing Q4 campaign performance to Q1 without accounting for seasonal variation in your core product will send you in the wrong direction.

    Getting Started Today

    The fastest way to get campaign visibility from your database is:

  • Confirm you're capturing UTM parameters at signup (if not, add this first it's a one-time fix)
  • Connect your database to a tool that can query it without requiring SQL expertise from your team
  • Build three core views: signups by campaign, conversion rate by campaign, revenue by campaign
  • Set those views to auto-refresh daily
  • Add one alert: notify your team if a high-spend campaign's daily signup rate drops by more than 20%
  • You don't need a data warehouse. You don't need a data engineer. The data is already in your database it just needs to be made accessible.

    AI for Database connects directly to your PostgreSQL, MySQL, Supabase, or other database and lets your marketing team ask questions in plain English, build live dashboards, and set up alerts without writing a line of SQL. Try it free at aifordatabase.com.

    Ready to try AI for Database?

    Query your database in plain English. No SQL required. Start free today.