MySQL
SQL Query
IF Condition
Database
Data Analysis

Count with IF condition in MySQL query

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Conditional counting is one of the most common SQL reporting tasks: count active users, failed orders, paid invoices, or rows matching some business rule. In MySQL, the usual solution is conditional aggregation with COUNT, SUM, IF, or CASE. The right choice depends on whether you want to count rows, count non-null values, or produce multiple category totals in one query.

The Key Rule Behind Conditional Counting

COUNT(expression) counts non-null results, not just rows. That is why this pattern works:

sql
COUNT(IF(status = 'paid', 1, NULL))

Rows where the condition is true produce 1, which is counted. Rows where the condition is false produce NULL, which is ignored.

Basic Example with COUNT(IF(...))

Suppose you have an orders table with status values.

sql
1SELECT
2    COUNT(*) AS total_orders,
3    COUNT(IF(status = 'paid', 1, NULL)) AS paid_orders,
4    COUNT(IF(status = 'failed', 1, NULL)) AS failed_orders
5FROM orders;

This gives multiple conditional counts in one pass over the table.

Equivalent Approach with SUM

Many developers prefer SUM because boolean conditions map naturally to 1 and 0.

sql
1SELECT
2    COUNT(*) AS total_orders,
3    SUM(IF(status = 'paid', 1, 0)) AS paid_orders,
4    SUM(IF(status = 'failed', 1, 0)) AS failed_orders
5FROM orders;

This is often easier to read when you want totals by condition. In MySQL, both styles are common.

Portable Version with CASE

If you want syntax that translates better across SQL databases, use CASE.

sql
1SELECT
2    COUNT(*) AS total_orders,
3    SUM(CASE WHEN status = 'paid' THEN 1 ELSE 0 END) AS paid_orders,
4    SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed_orders
5FROM orders;

This is the most portable conditional aggregation pattern and is often preferred in shared SQL codebases.

Grouped Conditional Counts

Conditional counting becomes more useful when combined with GROUP BY.

sql
1SELECT
2    customer_id,
3    COUNT(*) AS total_orders,
4    SUM(CASE WHEN status = 'paid' THEN 1 ELSE 0 END) AS paid_orders,
5    SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed_orders
6FROM orders
7GROUP BY customer_id;

Now each customer gets separate totals by status.

Counting with More Complex Conditions

You are not limited to equality checks. Any boolean predicate works.

sql
1SELECT
2    SUM(CASE WHEN total_amount >= 100 THEN 1 ELSE 0 END) AS high_value_orders,
3    SUM(CASE WHEN created_at >= '2026-03-01' THEN 1 ELSE 0 END) AS march_orders
4FROM orders;

This is especially useful in dashboards where several metrics come from the same dataset.

COUNT(*) vs COUNT(column)

Be careful with null handling. COUNT(*) counts rows. COUNT(column) counts only rows where that column is not null.

That means:

  • 'COUNT(*) is for total row count'
  • 'COUNT(email) ignores rows where email is null'

If your conditional logic depends on nullable columns, test the behavior explicitly.

Performance Notes

Conditional aggregation is usually efficient because it computes several metrics in one query instead of running separate queries. Still, performance depends on filtering and grouping:

  • index columns used in WHERE
  • index grouping keys when large scans happen often
  • avoid unnecessary subqueries when one grouped aggregate will do

The conditional expression itself is rarely the bottleneck. Table size, filtering, and grouping strategy matter more.

Common Pitfalls

  • Assuming COUNT(expression) counts false values as zero instead of skipping nulls.
  • Mixing COUNT(*) and COUNT(column) without understanding null behavior.
  • Writing several separate queries instead of one conditional aggregate query.
  • Using IF everywhere when CASE would be clearer or more portable.
  • Forgetting that grouped reports need GROUP BY on every non-aggregated selected column.

Summary

  • Conditional counting in MySQL is usually done with COUNT(IF(...)), SUM(IF(...)), or SUM(CASE ...).
  • 'COUNT(expression) counts non-null results, which is why the NULL trick works.'
  • 'SUM(CASE ...) is the clearest and most portable approach in many teams.'
  • Group conditional counts with GROUP BY to build useful reports in one query.
  • Validate null behavior and indexing when reports become more complex.

Course illustration
Course illustration

All Rights Reserved.