MySQL
SUM IF
COUNT IF
SQL queries
database management

MySql is it possible to 'SUM IF' or to 'COUNT IF'?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

MySQL does not expose built in functions named SUM_IF or COUNT_IF, but you can express the same behavior with conditional aggregation. This pattern is one of the most useful SQL techniques for dashboards, billing summaries, and operational metrics. The key is to model each metric as an aggregate over a condition, then group once and return many counters in a single query.

Why Conditional Aggregation Matters

Many reporting queries need values such as open ticket count, resolved ticket count, and overdue ticket count side by side. Running one query per metric is wasteful and can return inconsistent snapshots if data changes between calls.

Conditional aggregation solves this by scanning grouped data once.

sql
1SELECT
2  team_id,
3  COUNT(*) AS total_tickets,
4  SUM(CASE WHEN status = 'OPEN' THEN 1 ELSE 0 END) AS open_tickets,
5  SUM(CASE WHEN status = 'RESOLVED' THEN 1 ELSE 0 END) AS resolved_tickets
6FROM tickets
7GROUP BY team_id;

This is the practical equivalent of COUNT IF.

SUM With Conditions

Use SUM when each matching row contributes a numeric amount.

sql
1SELECT
2  account_id,
3  SUM(CASE WHEN kind = 'CREDIT' THEN amount ELSE 0 END) AS credit_total,
4  SUM(CASE WHEN kind = 'DEBIT' THEN amount ELSE 0 END) AS debit_total
5FROM ledger_entries
6GROUP BY account_id;

This is the practical equivalent of SUM IF. It stays readable and works across SQL engines, not only MySQL.

MySQL also allows boolean expressions inside numeric aggregates.

sql
1SELECT
2  team_id,
3  SUM(status = 'OPEN') AS open_count
4FROM tickets
5GROUP BY team_id;

This is concise, but the CASE form is clearer for mixed teams and cross database portability.

COUNT Style Alternatives

Three common patterns are valid.

  1. SUM(CASE WHEN cond THEN 1 ELSE 0 END).
  2. COUNT(CASE WHEN cond THEN 1 END).
  3. SUM(cond) in MySQL only.

Example with distinct users and event categories:

sql
1SELECT
2  DATE(created_at) AS day,
3  COUNT(*) AS events,
4  COUNT(CASE WHEN event_type = 'LOGIN' THEN 1 END) AS login_events,
5  COUNT(DISTINCT CASE WHEN event_type = 'PURCHASE' THEN user_id END) AS buyers
6FROM audit_events
7GROUP BY DATE(created_at)
8ORDER BY day;

The distinct conditional count is useful for product analytics.

Building Ratios Safely

Conditional totals are often used to compute rates. Always guard division by zero.

sql
1SELECT
2  team_id,
3  SUM(status = 'RESOLVED') AS resolved_count,
4  COUNT(*) AS total_count,
5  ROUND(
6    100.0 * SUM(status = 'RESOLVED') / NULLIF(COUNT(*), 0),
7    2
8  ) AS resolved_pct
9FROM tickets
10GROUP BY team_id;

Using NULLIF prevents runtime errors when a group has no rows in edge conditions.

Performance Notes

Conditional aggregation is CPU efficient compared with many separate grouped queries, but indexing still matters.

  • Index group keys such as team_id and created_at.
  • Index high selectivity filter columns used in WHERE before grouping.
  • Keep expressions in WHERE sargable when possible.
  • Pre aggregate into summary tables for very large time series dashboards.

Also consider filtering early with WHERE before aggregation instead of filtering late with HAVING unless you truly need aggregated predicates.

Example End To End Report Query

This query returns daily operational metrics in one result set.

sql
1SELECT
2  DATE(created_at) AS report_day,
3  COUNT(*) AS total_rows,
4  SUM(priority = 'HIGH') AS high_priority_rows,
5  SUM(status = 'OPEN') AS open_rows,
6  SUM(status = 'OPEN' AND due_at < CURRENT_DATE()) AS overdue_open_rows,
7  SUM(CASE WHEN status = 'OPEN' THEN estimated_hours ELSE 0 END) AS open_estimated_hours
8FROM tasks
9WHERE created_at >= CURRENT_DATE() - INTERVAL 30 DAY
10GROUP BY DATE(created_at)
11ORDER BY report_day DESC;

One query can now power several dashboard widgets without duplicated logic.

Common Pitfalls

  • Expecting literal COUNT_IF and SUM_IF function names in MySQL.
  • Forgetting ELSE 0 in conditional sums and getting null driven surprises.
  • Mixing WHERE and HAVING incorrectly.
  • Counting distinct entities without conditional DISTINCT logic.
  • Computing percentages without NULLIF, causing divide by zero issues.

Summary

  • MySQL supports COUNT IF and SUM IF behavior through conditional aggregation.
  • 'SUM(CASE WHEN ... THEN 1 ELSE 0 END) is the most portable counting style.'
  • Boolean SUM(condition) is concise in MySQL but less portable.
  • Conditional aggregates let you compute many KPIs in one grouped query.
  • Add defensive ratio logic and proper indexing for reliable production reports.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.