Skip to main content

FROM — Marketing Cloud SQL reference

Where the rows come from. Data Extensions vs System Data Views, table aliases, and the production rule that protects you from views that vanish.

Reference·Last updated 2026-05-07·Drafted by Lira · Edited by German Medina

FROM tells the SQL engine where to read. In Marketing Cloud you have exactly two source types: a Data Extension you (or someone in the org) created, and a System Data View (_Subscribers, _Sent, _Open, _Click, _Bounce, _Job, etc.) that Salesforce maintains. Get the source wrong and the query is correct against nothing useful.

Official syntax

FROM accepts a single table or view, optionally with an alias, plus chained JOIN clauses for additional sources. There are no subqueries in FROM in the supported subset — what reads as FROM (SELECT ...) sub in standard T-SQL won't run reliably here. Stage into an intermediate Data Extension instead.

-- Plain FROM, single Data Extension
SELECT SubscriberKey, EmailAddress
FROM master_subscribers;

-- With alias (recommended for readability — short, lowercase)
SELECT s.SubscriberKey, s.EmailAddress
FROM master_subscribers s;

-- With JOIN to a second source
SELECT s.SubscriberKey, p.LastPurchase
FROM master_subscribers s
INNER JOIN purchases p
  ON s.SubscriberKey = p.SubscriberKey;

-- FROM a System Data View (Salesforce-maintained)
SELECT SubscriberKey, EventDate
FROM _Sent
WHERE EventDate >= DATEADD(day, -7, GETDATE());

The two source types and their identifiers:

| Source | How you reference it | Who controls it | |---|---|---| | Data Extension | The DE name as configured (case-insensitive) | You / your org — you can ALTER it via the UI | | System Data View | Underscore-prefixed name (_Subscribers, _Sent, _Open, _Click, _Bounce, _Unsubscribe, _Job, etc.) | Salesforce — schema is published in Help, but the row set behavior is not your contract |

Reference:

What survives in production

Always alias multi-source queries

-- AT RISK — when the JOIN gets a third or fourth source, qualifying
-- columns by full table name becomes noise; if two DEs both have
-- "Status", the query parses but reads the wrong column
SELECT
  master_subscribers.SubscriberKey,
  purchases.LastPurchase,
  loyalty_tier.TierName
FROM master_subscribers
INNER JOIN purchases ON master_subscribers.SubscriberKey = purchases.SubscriberKey
INNER JOIN loyalty_tier ON master_subscribers.LoyaltyTier = loyalty_tier.TierCode;

-- DURABLE — short lowercase aliases, every column qualified, the
-- next dev sees which source each value comes from at a glance
SELECT
  s.SubscriberKey,
  p.LastPurchase,
  lt.TierName
FROM master_subscribers s
INNER JOIN purchases p
  ON s.SubscriberKey = p.SubscriberKey
INNER JOIN loyalty_tier lt
  ON s.LoyaltyTier = lt.TierCode;

The convention that holds up across the SQL section:

  • Short single-letter or two-letter aliases for the primary tables (s for subscribers, p for purchases, lt for loyalty_tier).
  • Always qualify columns when you have more than one source — even if today no name conflicts, tomorrow's column add will create one silently.
  • The first source in FROM is the "left" side of every subsequent JOIN. Pick it intentionally, not by typing order.

Snapshot System Data Views before reading them in production

_Sent, _Open, _Click, _Bounce, _Unsubscribe and friends look like persistent tables. They are not. After a Send Definition rotation, a Send Classification change, or a Salesforce platform update, the row set can shift or empty silently. A Journey query that reads _Sent directly and never enters anyone is the failure shape.

Naming conventions decide whether FROM is readable

A FROM master_subscribers reads cleanly because the DE name communicates ownership and content. A FROM Subscribers_v2_final_USE_THIS is a hostage note — the next dev has to guess which version, which owner, which run. Decide the naming convention before the first DE is created (see gotchas — #7 and the upcoming Style Guide).

The shape we use:

| Prefix | Holds | |---|---| | DE_ | Data Extension (master, owned by the implementation) | | de_stg_ | Staging DE — rebuilt on every run, safe to truncate | | de_log_ | Run log — append-only, indexed by date | | de_log_<sdv>_ | Snapshot of a System Data View |

FROM resolves DE names case-insensitively, but matching case in your queries to the DE configuration makes diffs cleaner.

What FROM cannot do

  • No subqueries in the supported subset (FROM (SELECT ...) sub). Stage into a real DE first, then FROM the staged DE.
  • No CTEs to substitute for FROM reliably across editions (see gotchas — #4).
  • No cross-tenant FROM. SQL Activities run inside a single Business Unit / MID; you can't reach across tenants from a single query.
  • No FROM against an Email Studio Data Extension that the Activity user can't see. Permissions are scoped per BU; if the Activity runs under a context that doesn't have read on the source DE, you get an empty result, not an error.

Quick decision

Read FROM <DataExtension> when:

  • You own (or your team owns) the DE, and its schema/contents are stable enough to depend on.
  • The data lives in MC and doesn't need to be assembled from external systems first.
  • The source DE is in the same Business Unit as the Activity (or accessible via a Shared Data Extension).

Read FROM _<SystemDataView> when:

  • You're snapshotting once, into a de_log_* DE you control. Then production queries read from the snapshot, not the SDV.
  • It's a one-shot diagnostic query (manual investigation, not a scheduled Activity).

Don't read FROM directly when:

  • The source is a System Data View AND the query is in a production Automation — snapshot first.
  • The source is going to be transformed heavily (CASE, string ops, dedup) — stage the raw FROM into a DE first, then transform the staged DE in a second Activity. Each Activity stays under the 30-min timeout (see gotchas — #3) and each row count is independently auditable.

Related

  • Basics — what an MC SQL Query Activity is and where it runs
  • SELECT — the projection that comes before FROM
  • MC SQL gotchas — see #6 for the System Data View persistence trap and #7 for naming conventions

More reference pages incoming: JOIN · WHERE · LIKE · CASE · INSERT INTO · String / Date / Numeric / Conversion / Aggregate / Null Functions · Style Guide.

Plus how-to snippets for common production debugging — email sends, value length, contact reach, etc.