---
name: gaql-query-patterns
description: Reusable GAQL query templates for Google Ads API. Auto-invoke when writing Google Ads queries, analyzing campaign data, querying performance metrics, or building custom reports.
---

# GAQL Query Patterns

Ready-to-use GAQL (Google Ads Query Language) query templates for common PPC analysis tasks.

## Campaign Queries

### 7-Day Campaign Spend Analysis

```sql
SELECT
    campaign.id,
    campaign.name,
    campaign.status,
    campaign.advertising_channel_type,
    campaign.bidding_strategy_type,
    campaign_budget.amount_micros,
    campaign_budget.explicitly_shared,
    metrics.cost_micros,
    metrics.impressions,
    metrics.clicks,
    metrics.conversions,
    metrics.conversions_value
FROM campaign
WHERE segments.date DURING LAST_7_DAYS
ORDER BY campaign.name
```

**Use for:** Recent spend analysis, budget utilization, campaign health checks

---

### Month-to-Date Pacing

```sql
SELECT
    campaign.id,
    campaign.name,
    campaign_budget.amount_micros,
    metrics.cost_micros
FROM campaign
WHERE segments.date DURING THIS_MONTH
ORDER BY campaign.name
```

**Use for:** Monthly pacing calculations, budget tracking

---

### Campaign Settings Audit

```sql
SELECT
    campaign.id,
    campaign.name,
    campaign.status,
    campaign.advertising_channel_type,
    campaign.bidding_strategy_type,
    campaign.target_cpa.target_cpa_micros,
    campaign.target_roas.target_roas,
    campaign_budget.amount_micros,
    campaign_budget.explicitly_shared
FROM campaign
WHERE campaign.status = 'ENABLED'
```

**Use for:** Configuration audits, bidding strategy checks, budget review

---

## Impression Share

### Search Impression Share Analysis

```sql
SELECT
    campaign.id,
    campaign.name,
    campaign.advertising_channel_type,
    metrics.search_impression_share,
    metrics.search_budget_lost_impression_share,
    metrics.search_rank_lost_impression_share,
    metrics.impressions
FROM campaign
WHERE segments.date DURING LAST_7_DAYS
  AND campaign.advertising_channel_type IN ('SEARCH', 'PERFORMANCE_MAX')
ORDER BY metrics.search_budget_lost_impression_share DESC
```

**Use for:** Diagnosing underspending, identifying budget constraints vs. quality issues

**Interpreting results:**
- High Budget Lost IS → increase budget to capture more impressions
- High Rank Lost IS → quality/relevance issue (not a budget problem)
- Both high → budget is primary constraint, but quality also needs work

---

## Search Terms

### Search Term Report (Last 30 Days)

```sql
SELECT
    search_term_view.search_term,
    campaign.name,
    ad_group.name,
    metrics.impressions,
    metrics.clicks,
    metrics.cost_micros,
    metrics.conversions,
    search_term_view.status
FROM search_term_view
WHERE segments.date DURING LAST_30_DAYS
  AND metrics.impressions > 0
ORDER BY metrics.cost_micros DESC
```

**Use for:** Negative keyword discovery, search term audits, intent analysis

---

### High-Spend Non-Converting Search Terms

```sql
SELECT
    search_term_view.search_term,
    campaign.name,
    metrics.clicks,
    metrics.cost_micros,
    metrics.conversions
FROM search_term_view
WHERE segments.date DURING LAST_30_DAYS
  AND metrics.conversions = 0
  AND metrics.cost_micros > 0
ORDER BY metrics.cost_micros DESC
```

**Use for:** Finding wasted spend, negative keyword candidates

---

## Keywords

### Keyword Performance with Quality Score

```sql
SELECT
    ad_group.name,
    ad_group_criterion.keyword.text,
    ad_group_criterion.keyword.match_type,
    ad_group_criterion.quality_info.quality_score,
    ad_group_criterion.quality_info.creative_quality_score,
    ad_group_criterion.quality_info.post_click_quality_score,
    ad_group_criterion.quality_info.search_predicted_ctr,
    metrics.impressions,
    metrics.clicks,
    metrics.cost_micros,
    metrics.conversions
FROM keyword_view
WHERE segments.date DURING LAST_30_DAYS
  AND ad_group_criterion.status = 'ENABLED'
ORDER BY metrics.cost_micros DESC
```

**Use for:** Quality score audits, keyword performance analysis

---

### Non-Serving Keywords (Zero Impressions)

```sql
SELECT
    campaign.name,
    ad_group.name,
    ad_group_criterion.keyword.text,
    ad_group_criterion.keyword.match_type,
    ad_group_criterion.status,
    metrics.impressions
FROM keyword_view
WHERE segments.date DURING LAST_180_DAYS
  AND campaign.status = 'ENABLED'
  AND ad_group.status = 'ENABLED'
  AND ad_group_criterion.status = 'ENABLED'
  AND metrics.impressions = 0
```

**Use for:** Finding dead keywords to clean up, account hygiene

---

## Ads

### RSA Performance

```sql
SELECT
    campaign.name,
    ad_group.name,
    ad_group_ad.ad.id,
    ad_group_ad.ad.responsive_search_ad.headlines,
    ad_group_ad.ad.responsive_search_ad.descriptions,
    ad_group_ad.ad_strength,
    metrics.impressions,
    metrics.clicks,
    metrics.conversions,
    metrics.cost_micros
FROM ad_group_ad
WHERE segments.date DURING LAST_30_DAYS
  AND ad_group_ad.ad.type = 'RESPONSIVE_SEARCH_AD'
  AND ad_group_ad.status = 'ENABLED'
ORDER BY metrics.impressions DESC
```

**Use for:** Ad performance review, RSA optimization

---

## Conversions

### Conversion Actions List

```sql
SELECT
    conversion_action.id,
    conversion_action.name,
    conversion_action.type,
    conversion_action.status,
    conversion_action.category,
    conversion_action.value_settings.default_value,
    conversion_action.counting_type,
    conversion_action.attribution_model_settings.attribution_model
FROM conversion_action
WHERE conversion_action.status = 'ENABLED'
ORDER BY conversion_action.name
```

**Use for:** Conversion tracking audits, identifying misconfigured actions

---

### Conversion Performance by Action

```sql
SELECT
    segments.conversion_action_name,
    segments.conversion_action_category,
    metrics.conversions,
    metrics.conversions_value,
    metrics.all_conversions,
    metrics.cost_micros
FROM campaign
WHERE segments.date DURING LAST_30_DAYS
ORDER BY metrics.conversions DESC
```

**Use for:** Understanding which conversion actions are firing, value distribution

---

## Geographic Performance

```sql
SELECT
    geographic_view.country_criterion_id,
    geographic_view.location_type,
    campaign.name,
    metrics.impressions,
    metrics.clicks,
    metrics.cost_micros,
    metrics.conversions
FROM geographic_view
WHERE segments.date DURING LAST_30_DAYS
ORDER BY metrics.cost_micros DESC
```

**Use for:** Geographic bid adjustments, location targeting audits

---

## Device Performance

```sql
SELECT
    campaign.name,
    segments.device,
    metrics.impressions,
    metrics.clicks,
    metrics.cost_micros,
    metrics.conversions,
    metrics.average_cpc
FROM campaign
WHERE segments.date DURING LAST_30_DAYS
ORDER BY campaign.name, segments.device
```

**Use for:** Device bid adjustments, mobile vs. desktop analysis

---

## Account-Level Summary

```sql
SELECT
    customer.id,
    customer.descriptive_name,
    metrics.cost_micros,
    metrics.impressions,
    metrics.clicks,
    metrics.conversions,
    metrics.conversions_value
FROM customer
WHERE segments.date DURING LAST_30_DAYS
```

**Use for:** High-level account overview, executive reporting

---

## Date Range Reference

| Keyword | Meaning |
|---------|---------|
| `YESTERDAY` | Yesterday only |
| `TODAY` | Today only |
| `LAST_7_DAYS` | Last 7 days |
| `LAST_14_DAYS` | Last 14 days |
| `LAST_30_DAYS` | Last 30 days |
| `THIS_MONTH` | Current month to date |
| `LAST_MONTH` | Previous calendar month |
| `THIS_WEEK_MON_TODAY` | This week (Monday to today) |

---

## Key Field Notes

### Micros Conversion
The API returns monetary values in **micros** (1,000,000 = $1):
```
50000000 micros = $50.00
1234567 micros = $1.23
```
Always divide by 1,000,000 when displaying to users.

### Impression Share Returns Decimals
The API returns impression share as **decimals (0.0 - 1.0)**, NOT percentages:
- API value `0.2464` = **24.64%** actual impression share
- Always multiply by 100 when displaying

### Metrics Require Date Segmentation
Any query with `metrics.*` fields MUST include a `WHERE segments.date` clause. Without it, the query will fail.

### Impression Share is Search/PMax Only
`search_impression_share`, `search_budget_lost_impression_share`, and `search_rank_lost_impression_share` are only available for Search and Performance Max campaigns.

### AND vs OR
GAQL doesn't support `OR`. Use `IN` instead:
```sql
-- Wrong
WHERE campaign.status = 'ENABLED' OR campaign.status = 'PAUSED'

-- Correct
WHERE campaign.status IN ('ENABLED', 'PAUSED')
```
