Learn SQL/Intermediate/Conditional Logic/SQL Multiple WHEN Conditions

SQL Multiple WHEN Conditions

Chain several WHEN branches together — Postgres checks them top to bottom and stops at the very first one that matches, even if a later condition would also have matched.

What & Why

A single WHEN only handles one condition. Real classification usually needs several tiers — "Low spend," "Medium spend," "High spend," and so on — which means stacking multiple WHEN ... THEN ... pairs inside one CASE: CASE WHEN cond1 THEN val1 WHEN cond2 THEN val2 ... END.

The genuinely important thing to understand here — more important than the syntax itself — is the evaluation order. Postgres checks each WHEN from top to bottom, in the exact order they're written, and stops the instant it finds one that's true. Every WHEN after that point is never even evaluated for that row, regardless of whether it would also have matched. This means the order you write your conditions in is not just a style choice — it can silently change your results if two conditions overlap.

See How It Works

BUSINESS QUESTION

Marketing compares the correct narrow-first campaign spend tiers with the same overlapping conditions written in the wrong order.

idnamechannelspendstart_dateend_datestatustarget_segment
1Spring Launchgoogle_ads55000.002024-01-152024-03-31activesmb
2Retention Webinaremail45000.002024-02-102024-04-15activeenterprise
3Finance Retargetinglinkedin50000.002024-03-122024-05-31activeenterprise
4Enterprise Searchgoogle_ads60000.002024-04-012024-06-30activeenterprise
Watch the first matching WHEN branch winExample 1 of 4
specific-first CASE compared with broad-first CASE
idnamespendspecific_firstbroad_first
1Spring Launch55000.00prioritystandard
2Retention Webinar45000.00??
3Finance Retargeting50000.00??
4Enterprise Search60000.00??

55,000 satisfies both thresholds: narrow-first returns priority, while broad-first stops too early at standard.

EXAMPLE QUERY
SELECT
  id,
  name,
  spend,
  CASE
    WHEN spend >= 55000 THEN 'priority'
    WHEN spend >= 50000 THEN 'standard'
    ELSE 'starter'
  END AS specific_first,
  CASE
    WHEN spend >= 50000 THEN 'standard'
    WHEN spend >= 55000 THEN 'priority'
    ELSE 'starter'
  END AS broad_first
FROM marketing.campaigns
ORDER BY id;
Now You Try

Practice this concept

Marketing compares narrow-first and broad-first CASE branches over the same overlapping spend thresholds.

Available schema
marketing

Prefix tables with marketing.table_name.

idnamespendspecific_firstbroad_first
marketing.campaigns
ColumnType
idinteger
nametext
channeltext
spendnumeric
start_datedate
end_datedate
statustext
target_segmenttext
legacy_idtext
query.sql
Intermediate business practice

Sign up free to try it on a real business scenario