xmetric / Use cases

Find wasted spend in a Google Ads search terms export

In the search terms report each row is one term in one ad group, so a term that cost a little in five places looks harmless in each. Add up each term across the whole account first, then flag the ones with no conversions anywhere: { FIXED [Search term] : SUM([Conversions]) } = 0. Drop your downloaded CSV below; the title lines and Total rows are skipped.

Drop your search terms CSV

Wasted spend by search term, and cost per conversion by match type

A made-up search terms download for an outdoor shop: 15 search terms spread over several campaigns and ad groups, with the title lines and Total rows a download includes. Computed from search-terms-report.csv (30 rows of made-up data). The Tableau calculation and the SQL below both produce these numbers.

Search terms, totalled across the account

Search termCampaignsClicksCostWasted spendConversions
how to clean hiking boots1108133.25133.250
hiking boots pdf size chart171101.43101.430
boots for snow25588.4888.480
hiking boot repair near me15575.0175.010
free hiking boots14362.5762.570
hiking jobs26046.9727.560
hiking boots women2100150.140.002.08
hiking boots287116.580.003.28
best hiking boots 2026260102.020.000.53
waterproof hiking boots275101.050.001.56
hiking boots wide fit16876.490.000.68
hiking socks13869.610.000.17
cheap hiking boots13239.520.000.23
trail running shoes24735.410.000.77
hiking boots sale13132.350.000.3

By match type

Match typeCostConversionsCost per conversionConv. value / costShare on non-converting terms
Broad match748.686.19120.950.8727.7%
Exact match (close variant)246.773.1678.091.1640.6%
Phrase match235.430.25941.720.0885.0%

Recompute it from your CSV

Download the search terms report as CSV and drop it here. Lines above the header row and rows that start with Total: are skipped, so totals aren't counted twice. Match the columns if your report uses other names. The file is read in this browser; nothing is uploaded.

No file loaded yet. You can also drop a CSV on this box.

Why one ad group at a time hides waste

The report splits each search term by campaign, ad group and match type. A broad-match query that cost a few dollars in each of five ad groups, with no conversions, never stands out in any one of them. Totalled across the account, it is one of your most expensive non-converting queries. The FIXED expression does that totalling before the zero-conversion check, so a term that converted anywhere is never flagged.

Getting the CSV out of Google Ads

  1. In Google Ads, open the Search terms report for the campaigns you want to check (it sits under Insights and reports).
  2. Pick a date range, and leave out the last week or so: recent clicks may still convert.
  3. Make sure the columns include the search term, match type, campaign, ad group, clicks, cost and conversions.
  4. Download it as .csv and drop it in the box above.

The sample uses column names as they typically appear in that download (Search term, Match type, Added/Excluded, Campaign, Ad group, Clicks, Impr., Cost, Conversions, Conv. value). Your account's language and column choices can change them; the box lets you match each one.

The Tableau calculation

Search terms, totalled across the account

On Rows: [Search term]. Each calculation below is one column.

// Term conversions, whole account
{ FIXED [Search term] : SUM([Conversions]) }

// Campaigns the term matched in
COUNTD([Campaign])

// Clicks
SUM([Clicks])

// Cost
SUM([Cost])

// Wasted spend: cost of terms with no conversions anywhere, not yet excluded
SUM(IF [Term conversions, whole account] = 0 AND [Added/Excluded] <> 'Excluded' THEN [Cost] ELSE 0 END)

// Conversions
SUM([Conversions])

By match type

On Rows: [Match type]. Each calculation below is one column.

// Term conversions, whole account
{ FIXED [Search term] : SUM([Conversions]) }

// Cost
SUM([Cost])

// Conversions
SUM([Conversions])

// Cost per conversion
SUM([Cost]) / SUM([Conversions])

// Conversion value per unit of cost (ROAS)
SUM([Conv. value]) / SUM([Cost])

// Share of cost on terms with no conversions anywhere
ZN(SUM(IF [Term conversions, whole account] = 0 THEN [Cost] END)) / SUM([Cost])

Reading the match type table

Close variants appear as their own match type labels, such as Exact match (close variant), so you can see whether they convert as well as true exact matches. In Tableau, dividing by a SUM of zero returns NULL, so a match type with no conversions shows a blank cost per conversion; the SQL gets the same with NULLIF.

The equivalent SQL

Search terms, totalled across the account

WITH terms AS (
  SELECT * FROM read_csv('search-terms-report.csv', skip = 2, header = true)
  WHERE "Search term" NOT LIKE 'Total:%'
),
flagged AS (
  SELECT *, SUM("Conversions") OVER (PARTITION BY "Search term") AS term_conversions
  FROM terms
)
SELECT "Search term",
       COUNT(DISTINCT "Campaign") AS campaigns,
       SUM("Clicks") AS clicks,
       SUM("Cost") AS cost,
       SUM(CASE WHEN term_conversions = 0 AND "Added/Excluded" <> 'Excluded' THEN "Cost" ELSE 0 END) AS wasted_spend,
       SUM("Conversions") AS conversions
FROM flagged
GROUP BY "Search term"
ORDER BY wasted_spend DESC, cost DESC;

By match type

WITH terms AS (
  SELECT * FROM read_csv('search-terms-report.csv', skip = 2, header = true)
  WHERE "Search term" NOT LIKE 'Total:%'
),
flagged AS (
  SELECT *, SUM("Conversions") OVER (PARTITION BY "Search term") AS term_conversions
  FROM terms
)
SELECT "Match type",
       SUM("Cost") AS cost,
       SUM("Conversions") AS conversions,
       SUM("Cost") / NULLIF(SUM("Conversions"), 0) AS cost_per_conversion,
       SUM("Conv. value") / SUM("Cost") AS roas,
       COALESCE(SUM("Cost") FILTER (WHERE term_conversions = 0), 0) / SUM("Cost") AS share_on_non_converting
FROM flagged
GROUP BY "Match type"
ORDER BY "Match type";

Before you add negatives

Questions people ask

Why does adding up the Cost column give me two or three times my spend?

The download ends with Total rows that repeat the sums. The box above skips rows that start with Total:, and the SQL filters them out with WHERE "Search term" NOT LIKE 'Total:%'.

Does a term with conversions in one campaign count as waste elsewhere?

No. The flag looks at the term's conversions across the whole account. To judge each campaign separately, use { FIXED [Search term], [Campaign] : SUM([Conversions]) } instead.

Is my Google Ads data uploaded?

No. The CSV is read and calculated in this browser tab; nothing is sent anywhere.

Related: FIXED expressions, ZN, CONTAINS. Test a formula in the playground.