Learn SQL/Intermediate/Grouping & Aggregation/SQL Conditional Aggregation

SQL Conditional Aggregation

Aggregate only rows matching a condition, WITHIN each group, using CASE inside the aggregate — the classic technique for splitting one column into several conditional columns.

What & Why

Conditional aggregation places a CASE WHEN expression inside an aggregate so one grouped query can calculate metrics for different subsets of the same rows.

COUNT(CASE WHEN qualified_at IS NOT NULL THEN 1 END) counts a lead only when the condition is true. Otherwise CASE returns NULL implicitly and COUNT skips it.

See How It Works

BUSINESS QUESTION

Marketing wants total, qualified, and converted leads for every acquisition source.

idcampaign_idemailcreated_atqualified_atconverted_atlead_scoresourcecountry
3011ana@example.com2024-01-21 09:10:00+002024-01-22 11:00:00+002024-02-02 10:00:00+0086google_adsUS
3021ben@example.com2024-01-24 12:40:00+00NULLNULL52google_adsCA
3032chloe@example.com2024-02-16 08:30:00+002024-02-18 14:20:00+00NULL74emailGB
3043dev@example.com2024-03-20 17:15:00+002024-03-21 09:00:00+002024-04-04 16:00:00+0091linkedinUS
Watch each marketing.leads row update its source metricsLead 1 of 4
COUNT(*) · COUNT(CASE WHEN qualified_at IS NOT NULL THEN 1 END) · COUNT(CASE WHEN converted_at IS NOT NULL THEN 1 END)
idsourcequalified_atconverted_atstate
301google_ads2024-01-22 11:00:00+002024-02-02 10:00:00+00CURRENT
302google_adsNULLNULLWAIT
303email2024-02-18 14:20:00+00NULLWAIT
304linkedin2024-03-21 09:00:00+002024-04-04 16:00:00+00WAIT
sourceleadsqualified_leadsconverted_leads
google_ads111

Lead 301 increments total, qualified, and converted for google_ads.

EXAMPLE QUERY
SELECT
  source,
  COUNT(*) AS leads,
  COUNT(CASE WHEN qualified_at IS NOT NULL THEN 1 END) AS qualified_leads,
  COUNT(CASE WHEN converted_at IS NOT NULL THEN 1 END) AS converted_leads
FROM marketing.leads
GROUP BY source
ORDER BY leads DESC, source;
Intermediate business practice

Sign up free to try it on a real business scenario