SOQL GROUP BY: Contacts by LeadSource

Aggregate SOQL that breaks contacts down by LeadSource, with COUNT, SUM, and the AggregateResult alias rules.

Updated 2026-09-09

Aggregate SOQL gives you a report-style breakdown without building a report: totals per LeadSource, returned as AggregateResult rows.

Contact records are the usual home of duplicate and data-quality problems because they arrive from forms, imports, and integrations at once.

The query

total is an alias. Without it, the column comes back as expr0, which is a common source of confusion when you consume the result in Apex.

Contacts per LeadSource
SELECT LeadSource, COUNT(Id) total
FROM Contact
GROUP BY LeadSource
ORDER BY COUNT(Id) DESC

Add a time window

This quarter only
SELECT LeadSource, COUNT(Id) total
FROM Contact
WHERE CreatedDate = THIS_QUARTER
GROUP BY LeadSource
ORDER BY COUNT(Id) DESC

Aggregate functions available

  • COUNT(field) / COUNT(Id) - number of rows in the group
  • COUNT_DISTINCT(field) - unique values
  • SUM(field), AVG(field), MIN(field), MAX(field) on numeric and date fields
  • GROUP BY ROLLUP(field) to add a grand-total row

Common mistakes to avoid

  • Use the API name Contact, not the UI label - the two differ on several standard objects.
  • Wrap literal text values in single quotes; date literals such as LAST_N_DAYS:30 must stay unquoted.
  • Run the query in a sandbox first if it feeds a bulk update - a WHERE clause that is one character off can select the whole table.
  • Every non-aggregate field in the SELECT list must appear in GROUP BY.
  • Aggregate queries return AggregateResult objects, not sObjects - you cannot dot-walk into them the same way.

Run it faster with TurboKit

Aggregates are the fastest way to sanity-check a data model before you trust a dashboard built on it.

TurboKit's AI SOQL builder lets you describe the result you want in plain English, returns the query, and exports the rows to CSV or Excel in the same panel - without leaving the Salesforce tab you are already on.

Frequently asked questions

What is AggregateResult?
It is the generic result type returned by any grouped or aggregate SOQL query. Fields are read by alias, and unaliased aggregate columns are named expr0, expr1, and so on.
Is there a row limit on GROUP BY queries?
Yes - grouped queries return at most 2,000 groups by default in Apex contexts. Filter more tightly, or use a report or bulk export if you need every group.
Can I group Contact by a formula field?
Only if the formula is deterministic and groupable. Text formulas usually work; formulas referencing other objects often do not, and the query returns an error rather than a partial result.

More from the SOQL Library

Related reading