Explain Codes LogoExplain Codes Logo

Count based on condition in SQL Server

sql
conditional-counting
sql-queries
database-optimization
Nikita BarsukovbyNikita Barsukov·Jan 19, 2025
TLDR

Count rows based on specific conditions in SQL Server by leveraging the SUM and CASE statements:

SELECT SUM(CASE WHEN condition THEN 1 ELSE 0 END) AS ConditionalCount FROM tableName;

Don't forget to replace condition with your requirement and tableName with the name of your table in the database.

For a generic count considering all rows, COUNT(*) serves best as it totals the rows irrespective of any condition.

Aggregating conditionally with SUM and CASE

If you're keen on counting conditionally for each row, the SUM(CASE WHEN...) approach is both succinct and efficient:

SELECT UserID, SUM(CASE WHEN name = 'system' THEN 1 -- "System" checks ELSE 0 END) AS TotalSystemRecords, COUNT(*) AS TotalRecordsPerUser -- Total count FROM SampleTable GROUP BY UserID; -- Grouping by User ID
/* "Ain't no system like a checked system!" */

This gives you a comprehensive count of rows where name equals 'system', in tandem with the total number of rows for each UserID.

Alternate counting with IIF

As an alternative, SQL Server's IIF function can offer a streamlined implementation of your conditional logic, increasing readability:

SELECT UserID, SUM(IIF(name = 'system', 1, 0)) AS TotalSystemRecords, COUNT(*) AS TotalRecords FROM SampleTable GROUP BY UserID;
/* "IIF you got the 'system', we got the count!" */

This achieves an identical result with a more approachable syntax, especially for users already familiar with logical functions.

Make sense of grouping

Grouping is your best friend when you wish to partition your counts by an identifier such as UserID. It ensures that counts are attributed to the correct user, effectively presenting the distribution of data.

Handling multiple conditions

There could be instances when you need to perform the count based on multiple conditions. Here is how you could extend your query:

SELECT UserID, SUM(CASE WHEN name = 'system' THEN 1 ELSE 0 END) AS SystemCount, SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) AS ActiveStatusCount, COUNT(*) AS TotalRecords FROM SampleTable GROUP BY UserID;
/* "Show me the counts, 'system' and 'active', side by side!" */

This query provides a granular understanding of the data distribution with counts for both 'system' and 'active' occurrences.

Verifying against expectations

Once you've run your query, it's a good idea to compare the output with your expectations or known information. This helps you ensure the accuracy of your condition checks and the legitimacy of your counts.

Tailoring to your needs

It's important to replace UserID, name, status, and SampleTable with the actual column and table names that correspond to your database schema.

Potential pitfalls to avoid

Wielding SQL efficiently means being mindful of possible errors. Misalignment in SQL syntax, a missing GROUP BY clause, or incorrect conditioning logic can all lead to misleading counts or SQL execution failures.

Making functions work for you

Mastering when to use SUM(CASE WHEN...), IIF, or COUNT(*) can yield more optimized queries, thereby improving performance, especially in scenarios with voluminous databases.