← All writing

Filter grouped totals with HAVING

MySQL 8.0+ / InnoDBSources checked 2026-09-14

A report needs customers whose outstanding invoice total exceeds a threshold. WHERE filters individual rows before grouping; HAVING filters grouped results. Putting the aggregate condition in the wrong stage either fails or changes the meaning.

Separate row eligibility from group eligibility

SELECT customer_id, SUM(outstanding_amount) AS outstanding
FROM invoices
WHERE tenant_id = 42
GROUP BY customer_id
HAVING SUM(outstanding_amount) > 10000;

This assumes outstanding_amount is an exact numeric amount in a single comparable currency and already follows the application's settlement rules. Do not sum unrelated currencies into one threshold.

Define the amount before writing the report

An invoice total is not necessarily its outstanding balance. Partial payments, credits, and write-offs can change the measure. If those are separate records, aggregate them at the correct grain before combining them to avoid multiplying values through joins.

Keep nonaggregated selected columns compatible with grouping rules. Do not disable strict SQL grouping modes to make an ambiguous report execute; decide which customer name or other attribute the result actually represents.

Test a customer below, exactly at, and above the threshold. Include multiple invoices and a partial payment in the fixture if that is part of the model. Verify whether the threshold comparison is strict or inclusive. That small choice should come from the report requirement, not from whichever operator happened to be typed first.

Reference

Official documentation.