marketing-cloud-sql-queries

Use this skill when writing, debugging, or optimizing SQL Query Activities in Salesforce Marketing Cloud Automation Studio. Trigger keywords: SFMC SQL, Marketing Cloud query activity, system data views, _Sent _Open _Click, Automation Studio SQL, SELECT INTO data extension. NOT for SOQL (Salesforce CRM queries against sObjects), NOT for standard SQL databases, NOT for Data Cloud ANSI SQL, NOT for Query Studio as a standalone topic.

Best use case

marketing-cloud-sql-queries is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use this skill when writing, debugging, or optimizing SQL Query Activities in Salesforce Marketing Cloud Automation Studio. Trigger keywords: SFMC SQL, Marketing Cloud query activity, system data views, _Sent _Open _Click, Automation Studio SQL, SELECT INTO data extension. NOT for SOQL (Salesforce CRM queries against sObjects), NOT for standard SQL databases, NOT for Data Cloud ANSI SQL, NOT for Query Studio as a standalone topic.

Teams using marketing-cloud-sql-queries should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/marketing-cloud-sql-queries/SKILL.md --create-dirs "https://raw.githubusercontent.com/PranavNagrecha/AwesomeSalesforceSkills/main/skills/data/marketing-cloud-sql-queries/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/marketing-cloud-sql-queries/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How marketing-cloud-sql-queries Compares

Feature / Agentmarketing-cloud-sql-queriesStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use this skill when writing, debugging, or optimizing SQL Query Activities in Salesforce Marketing Cloud Automation Studio. Trigger keywords: SFMC SQL, Marketing Cloud query activity, system data views, _Sent _Open _Click, Automation Studio SQL, SELECT INTO data extension. NOT for SOQL (Salesforce CRM queries against sObjects), NOT for standard SQL databases, NOT for Data Cloud ANSI SQL, NOT for Query Studio as a standalone topic.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# Marketing Cloud SQL Queries

This skill activates when a practitioner needs to write, debug, or optimize a SQL Query Activity in Salesforce Marketing Cloud Automation Studio. It covers T-SQL dialect rules, system data view access, performance constraints, and the SELECT INTO output model — and explicitly excludes SOQL, standard relational SQL databases, and Data Cloud SQL.

---

## Before Starting

Gather this context before working on anything in this domain:

- Confirm the target is a Marketing Cloud Data Extension (DE), not a CRM object. SQL Query Activities output ONLY to a DE via SELECT INTO — there are no result sets, cursors, or direct API responses.
- Ask whether the Query Activity action is set to **Overwrite** (default — truncates target before insert) or **Update** (upserts based on Primary Key). Choosing the wrong action overwrites subscriber data silently.
- Determine the date range. System data views (_Sent, _Open, _Click, _Bounce, _Subscribers, _Job) retain only approximately 6 months of data. Queries spanning longer ranges return incomplete results without error.

---

## Core Concepts

### T-SQL Dialect, Not Standard SQL

Marketing Cloud SQL Query Activities use a T-SQL-like dialect, not ANSI SQL, MySQL, or PostgreSQL. Key differences that cause real failures:

- Date functions: use `GETDATE()`, `DATEADD()`, `DATEDIFF()`, `CONVERT()` — never `NOW()`, `SYSDATE()`, or `DATE_SUB()`
- No stored procedures, no temp tables (`#tmp`), no cursors, no CTEs (`WITH` clauses are not supported)
- Window functions (ROW_NUMBER OVER, RANK OVER) are NOT supported
- `IS NULL` / `IS NOT NULL` are required for null checks — `= NULL` always evaluates false
- `DISTINCT`, `GROUP BY`, `HAVING`, and `TOP` are supported

### SELECT INTO Is the Only Output Mechanism

Every query must end with a SELECT INTO targeting a DE:

```sql
SELECT
    s.SubscriberKey,
    s.EmailAddress,
    s.EventDate
INTO target_DE_name
FROM _Sent s
WHERE s.EventDate >= DATEADD(DAY, -30, GETDATE())
```

There is no `INSERT INTO ... SELECT` syntax. The target DE must already exist. Column names in the SELECT list must match DE field names exactly (case-insensitive but name-sensitive). If a column is not in the SELECT list, it receives NULL or its default value.

### System Data Views and Their Retention Window

Six system data views are queryable only from a SQL Query Activity (not via API):

| View | Content | Retention |
|---|---|---|
| `_Sent` | Send events per job/subscriber | ~6 months |
| `_Open` | Open tracking events | ~6 months |
| `_Click` | Click tracking events | ~6 months |
| `_Bounce` | Bounce events | ~6 months |
| `_Subscribers` | Subscriber list status | Current state |
| `_Job` | Email send job metadata | ~6 months |

Joins between system data views must use `JobID` + `SubscriberKey` as the composite key. Joining on `EmailAddress` alone causes fan-out because one email address can have multiple SubscriberKey values across lists.

---

## Common Patterns

### Pattern 1: Segment Engaged Subscribers from System Data Views

**When to use:** Building a re-engagement or suppression segment based on recent open or click activity.

**How it works:** Scope the date range to 90 days or less to stay well within the 6-month retention window and avoid full-table scans. Join `_Open` to a subscriber DE on `SubscriberKey` to enrich output.

```sql
SELECT DISTINCT
    o.SubscriberKey,
    o.EmailAddress,
    MAX(o.EventDate) AS LastOpenDate
INTO Engaged_Last_90_Days
FROM _Open o
WHERE o.EventDate >= DATEADD(DAY, -90, GETDATE())
GROUP BY o.SubscriberKey, o.EmailAddress
```

**Why not the alternative:** Using `SELECT *` or omitting the date WHERE clause causes a full scan of all 6 months of open data. On high-volume accounts this reliably hits the 30-minute timeout.

### Pattern 2: Upsert Subscriber Attributes from a Source DE

**When to use:** Syncing computed values (e.g., loyalty tier, predicted churn score) into a master profile DE without destroying existing rows.

**How it works:** Set the Query Activity action to **Update** and ensure the target DE has a Primary Key field that matches the join key. Use a straightforward SELECT INTO — the platform handles the upsert logic.

```sql
SELECT
    s.SubscriberKey,
    s.LoyaltyTier,
    s.UpdatedDate
INTO Master_Profile_DE
FROM Source_Tier_DE s
WHERE s.UpdatedDate >= DATEADD(DAY, -1, GETDATE())
```

**Why not the alternative:** Using **Overwrite** action on a master profile DE wipes all rows not present in the current query result, including subscribers who did not interact during the query window.

---

## Decision Guidance

| Situation | Recommended Approach | Reason |
|---|---|---|
| Query must append new rows without removing existing ones | Set Query Activity action to **Update**; ensure target DE has Primary Key | Overwrite (default) truncates the target before inserting |
| Date range exceeds 6 months | Split into multiple queries per 6-month window and union via intermediate DEs | System data views do not retain data beyond ~6 months |
| Query frequently times out | Add `WHERE EventDate >= DATEADD(DAY, -N, GETDATE())` using indexed EventDate | Non-date-bounded queries do full scans |
| Need to deduplicate output rows | Use `SELECT DISTINCT` or `GROUP BY` with `MAX()` / `MIN()` aggregates | Window functions like `ROW_NUMBER() OVER` are not supported |
| Need to test a query before automation | Use Query Studio (SF Labs AppExchange app) against live data | Automation Studio has no interactive result preview |
| Joining system data view to subscriber DE | Use `JobID + SubscriberKey` as composite join key | Joining on `EmailAddress` alone causes fan-out on multi-list accounts |

---

## Recommended Workflow

Step-by-step instructions for an AI agent or practitioner working on this task:

1. **Clarify the output target and action setting.** Confirm the target DE name exists, identify its Primary Key field, and determine whether the Query Activity action should be Overwrite (full refresh) or Update (upsert/append).
2. **Identify source data views and date bounds.** Determine which system data views or DEs are involved. If using system data views, establish a date range no longer than 6 months; prefer 30–90 days for performance.
3. **Draft the SELECT INTO statement.** Use T-SQL date functions (`GETDATE()`, `DATEADD()`). Ensure all WHERE conditions reference indexed or Primary Key columns. Avoid `SELECT *` — enumerate only needed columns.
4. **Validate join keys.** If joining a system data view to a DE, use `JobID + SubscriberKey` as the composite key. If joining DEs to each other, use the DE Primary Key field.
5. **Test in Query Studio before embedding in Automation.** Run the query in Query Studio (SF Labs AppExchange) to verify result shape, row count, and absence of timeout. Confirm the output matches expected DE column names.
6. **Embed in Automation Studio and set the action.** Add the Query Activity to the automation, set Overwrite or Update explicitly (do not rely on the default), and schedule or trigger appropriately.
7. **Monitor the first run.** Confirm the target DE row count matches expectation. Check Automation Studio activity history for errors or timeouts. If run time exceeds 20 minutes, narrow the date range further.

---

## Review Checklist

Run through these before marking work in this area complete:

- [ ] SELECT INTO references a DE that already exists with matching column names
- [ ] Query Activity action (Overwrite vs Update) is explicitly set and correct for the use case
- [ ] WHERE clause scopes date range to 6 months or less for any system data view source
- [ ] All WHERE and JOIN conditions reference indexed columns or Primary Key fields
- [ ] T-SQL date functions used throughout — no `NOW()`, `SYSDATE()`, or `DATE_SUB()`
- [ ] No stored procedures, temp tables, CTEs (`WITH`), or window functions in query
- [ ] NULL checks use `IS NULL` / `IS NOT NULL`, not `= NULL`
- [ ] Query tested in Query Studio before embedding in Automation

---

## Salesforce-Specific Gotchas

Non-obvious platform behaviors that cause real production problems:

1. **Overwrite Is the Default — Silently Wipes Target DE** — If the Query Activity action is not explicitly set to Update, it defaults to Overwrite, which truncates the entire target DE before inserting results. A query that returns zero rows (e.g., due to a typo in a date filter) will silently empty the target DE.
2. **30-Minute Hard Timeout with No Partial Commit** — Queries that exceed 30 minutes are killed with no partial results written to the target DE. The Automation activity shows an error, but the target DE state depends on whether Overwrite had already truncated it. Scope date ranges tightly to prevent this.
3. **System Data Views Are Read-Only and Not Visible in DE Navigator** — System data views cannot be browsed in Contact Builder or All Subscribers. They appear only in SQL Query Activity context. Attempting to import, export, or modify them through other tools fails silently or with a generic error.

---

## Output Artifacts

| Artifact | Description |
|---|---|
| SQL Query Activity statement | A complete T-SQL SELECT INTO statement ready to paste into Automation Studio Query Activity |
| Query Activity configuration note | Specifies target DE name, Primary Key field, and action setting (Overwrite/Update) |
| Query Studio test checklist | Steps to validate query result shape and row count before automation embedding |

---

## Related Skills

- admin/marketing-cloud-engagement-setup — Use when the underlying MC org, business unit, or Automation Studio configuration needs to be validated before query work begins
- data/data-extension-design — Use when the target or source DE structure needs to be designed or reviewed as part of the query project
- data/bulk-api-and-large-data-loads — Use when data movement is between SFMC and the Salesforce CRM org rather than within SFMC itself

Related Skills

experience-cloud-security

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when configuring access controls, sharing, or site security for authenticated or guest Experience Cloud (community) users: external OWD, Sharing Sets, Share Groups, CSP, clickjack protection, guest user record access. NOT for internal sharing model configuration (use sharing-and-visibility).

headless-experience-cloud

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when building custom frontends (React, Vue, mobile, static sites) that consume Salesforce CMS content via the Connect REST API headless delivery endpoint. Triggers: 'headless Salesforce CMS', 'deliver CMS content to external frontend', 'React app Salesforce content API', 'custom frontend Experience Cloud data', 'CMS delivery channel API'. NOT for standard Experience Builder site development. NOT for CMS Connect (3rd-party CMS federation into Experience Builder). NOT for Experience Cloud LWC components rendered inside a site.

experience-cloud-search-customization

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when configuring or extending search on an Experience Cloud site — covering Search Manager scope configuration, LWR vs Aura search component selection, federated search setup, guest user search access, and custom search result components. NOT for SOSL/SOQL query development. NOT for internal Salesforce global search or Einstein Search for agents.

experience-cloud-multi-idp-sso

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when configuring multiple identity providers (OIDC and/or SAML) on a single Experience Cloud site or across tenant-specific portals in the same org — covering auth provider registration, Start SSO URL routing, Federation ID mapping, RegistrationHandler implementation, and simultaneous SP+IdP topology. Trigger keywords: multiple identity providers Experience Cloud, multi-tenant SSO community portal, vendor and citizen portal same site, OIDC SAML both on login page, tenant-specific login routing community. NOT for internal Salesforce employee SSO configuration. NOT for single auth provider setups — see experience-cloud-authentication for basic SSO.

experience-cloud-lwc-components

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when building custom LWC components for Experience Cloud (Experience Builder sites, LWR portals, Aura-based communities). Covers community context imports, guest user Apex access patterns, navigation API differences between LWR and Aura, and JS-meta.xml target configuration for Experience Builder exposure. NOT for internal LWC components deployed to Lightning App Builder or standard record pages (see lwc/lwc-development). NOT for Aura community components. Trigger keywords: build LWC for Experience Cloud, custom component community portal LWC, guest user LWC component, community context import salesforce, lightningCommunity target, @salesforce/community, guest Apex.

experience-cloud-authentication

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when building custom login pages, social SSO flows, self-registration flows, or passwordless OTP login for Experience Cloud (community) sites. Trigger keywords: custom login page Experience Cloud, social SSO community portal, passwordless login Experience Cloud, self-registration custom flow, headless authentication community, auth provider OIDC SAML site. NOT for internal SSO configuration (use identity/sso skills). NOT for standard username/password authentication with no customization.

experience-cloud-api-access

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when configuring or troubleshooting API access for Experience Cloud external users and guest users: guest user Apex data access, Customer Community Plus or Partner Community REST/SOAP API access, external user OAuth scopes, and sharing enforcement on API responses. Trigger keywords: Experience Cloud API access external user, community user REST API, guest user API limits, Customer Community API permissions, external user OAuth. NOT for internal Salesforce API authentication, non-community OAuth flows, or internal user API security.

net-zero-cloud-setup

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when configuring Salesforce Net Zero Cloud — including Scope 1/2/3 emission source modeling via the StnryAssetCrbnFtprnt / VehicleAssetCrbnFtprnt / Scope3CrbnFtprnt object families, emission factor library setup (EmssnFctr / EmssnFctrSet), DPE-driven carbon calculation jobs, supplier engagement scoring, and CSRD / ESRS / TCFD disclosure pack mapping. Triggers on: Net Zero Cloud setup, Sustainability Cloud carbon accounting, Scope 1 2 3 emissions Salesforce, emission factor library, supplier engagement Net Zero, ESG disclosure pack mapping. NOT for ESG content scoring (use Marketing Cloud), NOT for general financial reporting (use Accounting Subledger), NOT for energy-only utility billing (use Energy & Utilities Cloud).

manufacturing-cloud-setup

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when configuring Salesforce Manufacturing Cloud — including Sales Agreement setup, Account-Based Forecasting (ABF) recalc jobs, run-rate management, Rebate Management programs, channel inventory tracking via Channel Revenue Management, and Group Membership / OrderItem-to-SalesAgreement reconciliation. Triggers on: Manufacturing Cloud setup, Sales Agreement Salesforce, account-based forecast recalculation, run rate manufacturing, rebate program setup, channel revenue management. NOT for general Sales Cloud opportunity-to-order flow (use standard Opportunity / Order), NOT for Field Service install-base management (use FSL skills), NOT for Automotive Cloud dealer modeling (use automotive-cloud-setup).

data-cloud-zero-copy-federation

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when configuring or troubleshooting Data Cloud Zero Copy / Lakehouse Federation against Snowflake, Databricks, BigQuery, or Redshift — including external Data Lake Object setup, query semantics through federation, refresh and cache behavior, and choosing federation versus physical ingestion. Triggers on: Data Cloud federated DLO setup, query latency against external warehouse, Snowflake/Databricks/BigQuery integration with Data Cloud, federation vs ingestion decision. NOT for physical Ingestion API streaming/bulk patterns (use data-cloud-integration-strategy), not for CRM Analytics external connectors (use analytics-external-data), not for outbound Data Cloud activation to external systems (use data-cloud-activation-development).

data-cloud-query-api

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when querying unified profile data, calculated insights, or Data Lake Objects from Data Cloud using ANSI SQL via the Query V2 or Query Connect APIs. Triggers on: SQL queries against Data Cloud, querying unified individuals, querying DMOs via API, paginating large Data Cloud result sets. NOT for SOQL queries against standard Salesforce objects, not for Data Cloud segment filtering in the UI, not for vector/semantic search (use data-cloud-vector-search-dev).

data-cloud-integration-strategy

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when designing or troubleshooting the data pipeline strategy for connecting source systems to Data Cloud — including ingestion API pattern selection (streaming vs. batch), connector type decisions, DSO-to-DLO-to-DMO pipeline lag, and lakehouse federation patterns. Triggers on: Data Cloud ingestion API setup, streaming vs batch connector decision, Data Cloud connector types, MuleSoft Direct for Data Cloud, data pipeline lag for segmentation. NOT for standard Salesforce integration patterns (use integration-patterns skill), not for querying Data Cloud once data is ingested (use data-cloud-query-api), not for configuring standard admin connectors through the UI only.