SapotaCorp

AMPscript Patterns: Lookups, Conditionals, and Safe Fallbacks

Personalization Strings handle 80% of what you need. AMPscript is the rest: cross-DE lookups, tiered logic, date formatting. Here are the three patterns we reach for most, with the fallback discipline that keeps emails from breaking.

AMPscript Patterns: Lookups, Conditionals, and Safe Fallbacks

Key takeaways

  • Personalization Strings handle 80 percent of email personalization; AMPscript handles the remaining 20: cross-DE lookups, tiered conditional logic, date and number formatting. 3 patterns appear in nearly every production engagement.
  • Lookup() pattern reads from another DE by key. Pull the customer's loyalty tier from Loyalty_DE, the recent order from Order_DE, the preferred language from Preferences_DE. The pattern is one line; the fallback discipline (IF EMPTY) prevents broken renders when the lookup misses.
  • Conditional tier logic with IF/ELSE branches the content based on subscriber attributes. The pattern suits "show tier-specific offer" or "show region- appropriate disclaimer". Keep the logic shallow (2 to 3 levels max); deeper nesting becomes unmaintainable.
  • Format() for dates and numbers prevents locale-mismatch bugs. The same subscriber data renders as "31/12/2025" in EU and "12/31/2025" in US; Format() enforces the correct locale per send. Default formats pick the org default — wrong for international sends. Always specify the format explicitly.

Personalization Strings cover the simple cases. AMPscript is what you reach for when the email needs to do more than inject a single value.

Three patterns we use on almost every production engagement:

  1. Looking up values from a non-sendable Data Extension
  2. Tiered conditional content based on subscriber state
  3. Formatting dates and numbers for display

The AMPscript block is wrapped in %%[ ... ]%%. Output of a variable comes from %%=v(@varName)=%%.

Pattern 1: Lookup across Data Extensions

The sendable DE usually doesn't hold every attribute the email needs. A common case: the email sends from each subscriber's assigned Sales Rep, but the rep's name, email, and phone live in a separate SalesRep_DE, not duplicated into the sendable.

Customer_DE (sendable):
  - CustomerID     <- Subscriber Key
  - EmailAddress
  - SalesRepID     <- just an ID

SalesRep_DE (non-sendable):
  - SalesRepID     <- Primary Key
  - RepName
  - RepEmail
  - RepPhone

Fetch the rep data at send time with Lookup():

%%[
VAR @repID, @repName, @repEmail, @repPhone

SET @repID    = AttributeValue("SalesRepID")
SET @repName  = Lookup("SalesRep_DE", "RepName",  "SalesRepID", @repID)
SET @repEmail = Lookup("SalesRep_DE", "RepEmail", "SalesRepID", @repID)
SET @repPhone = Lookup("SalesRep_DE", "RepPhone", "SalesRepID", @repID)

/* Always handle the not-found case */
IF EMPTY(@repName) THEN
  SET @repName  = "Customer Care Team"
  SET @repEmail = "support@company.com"
  SET @repPhone = "1800 xxxx"
ENDIF
]%%

<p>Your account manager:</p>
<p><strong>%%=v(@repName)=%%</strong></p>
<p>%%=v(@repEmail)=%% | %%=v(@repPhone)=%%</p>

Lookup syntax:

Lookup("TableName", "FieldToReturn", "FieldToMatch", ValueToMatch)

The pair that gets swapped constantly is positions 2 and 3 - FieldToReturn and FieldToMatch. Order wrong = Lookup silently returns empty. No error, just blank output.

/* wrong - argument positions swapped */
SET @repName = Lookup("SalesRep_DE", "SalesRepID", "RepName", @repID)

/* right */
SET @repName = Lookup("SalesRep_DE", "RepName", "SalesRepID", @repID)

Pattern 2: Tiered conditional content

Loyalty emails routinely say different things depending on the subscriber's current state:

%%[
VAR @points, @message, @pointsLeft

SET @points = AttributeValue("LoyaltyPoints")

IF @points >= 1000 THEN
  SET @message    = "You've reached GOLD tier!"
  SET @pointsLeft = 0
ELSEIF @points >= 500 THEN
  SET @message    = "You're at SILVER tier"
  SET @pointsLeft = Subtract(1000, @points)
ELSE
  SET @message    = "You're at STANDARD tier"
  SET @pointsLeft = Subtract(500, @points)
ENDIF
]%%

<p>%%=v(@message)=%%</p>
%%[IF @pointsLeft > 0 THEN]%%
  <p>Earn <strong>%%=v(@pointsLeft)=%%</strong> more points to reach the next tier!</p>
%%[ENDIF]%%

Two scripting blocks here: the top one sets variables, the inline IF decides whether to render a paragraph at all.

When conditional content is structural (show or hide whole blocks of HTML), either AMPscript inline IF or a Dynamic Content Block works. Dynamic Content is nicer for non-developers to maintain; AMPscript is nicer when logic is complex or needs lookups.

Pattern 3: Formatting values for display

Raw data rarely matches how humans read it. 1500000 in a DE should display as 1,500,000 VND in the email. 2024-01-15 should display as 15/01/2024.

%%[
VAR @today, @amount, @formattedAmount

SET @today = Format(Now(), "dd/MM/yyyy")
SET @amount = AttributeValue("OrderAmount")
SET @formattedAmount = Format(@amount, "N0")
]%%

Order date: %%=v(@today)=%%
Amount: %%=v(@formattedAmount)=%% VND

Format(value, "N0") = number with thousands separators, no decimals. Format(date, "dd/MM/yyyy") = day/month/year. Now() = current send time.

Other useful format strings:

  • "yyyy-MM-dd" for ISO dates
  • "hh:mm" for 12-hour time
  • "HH:mm" for 24-hour time
  • "C" for currency (locale-aware, use cautiously in international sends)

The three mistakes we still see

Mistake 1: No EMPTY() check after Lookup

Lookup returns empty when the match fails. Without an explicit fallback, the email just shows nothing where the data should be. Always:

SET @rep = Lookup("SalesRep_DE", "RepName", "SalesRepID", @repID)
IF EMPTY(@rep) THEN
  SET @rep = "Customer Care Team"
ENDIF

Mistake 2: Unclosed AMPscript blocks

Forgetting to close %%[ breaks rendering on the whole email. Test in Preview & Test immediately after writing AMPscript - if the Preview shows error text, the syntax is wrong and the email won't send.

Mistake 3: AMPscript in the Subject Line

Same rule as Personalization Strings: Subject Line does not render AMPscript. Move the logic upstream, pre-compute a field in the DE, and use a plain Personalization String in the subject.

Takeaway

AMPscript earns its place in the project when the email needs cross-DE data, conditional logic, or formatted values. Three patterns cover 90% of the real-world use cases: Lookup with IF EMPTY fallback, IF/ELSEIF/ELSE for tiers, and Format() for numbers and dates. Preview & Test with multiple data profiles catches both logic bugs and syntax errors before they go to the full list.


Writing AMPscript for a production SFMC build? Our Salesforce team reviews and ships complex AMPscript on Marketing Cloud engagements. Get in touch ->

See our full platform services for the stack we cover.

Contact Us Now

Share Your Story

We build trust by delivering what we promise – the first time and every time!

We'd love to hear your vision. Our IT experts will reach out to you during business hours to discuss making it happen.

WHY CHOOSE US

"Collaborate, Elevate, Celebrate where Associates - Create Project Excellence"

SapotaCorp beyond the IT industry standard, we are

  • Certificated
  • Assured quality
  • Extra maintenance

Tell us about your project