COUNT vs COUNTX in DAX: Understanding Counting Functions

September 23, 2026 103 visits

In this article, we will learn how to use COUNT and COUNTX in DAX to count values in a table. We will also understand an important difference between counting an existing column and counting the result of an expression.

📥 Practice Data:
Download Practice Data Free

🎥 Prefer learning through video?
DAX YouTube Playlist

What Are COUNT and COUNTX in DAX?

COUNT and COUNTX are DAX counting functions, but they work differently.
COUNT counts the non-blank values in a specified column, while COUNTX evaluates an expression row by row and counts the non-blank results.

Function How it works
COUNT Counts non-blank values directly from a column.
COUNTX Iterates through a table, evaluates an expression for each row, and counts the non-blank results.

1. COUNT Function

The first query uses COUNT to count values from three different columns in the AvgTable table.

Query

DAX Query
EVALUATE
	ROW(
		"Col A", COUNT(AvgTable[Col A]),
		"Col B", COUNT(AvgTable[Col B]),
		"Col C", COUNT(AvgTable[Col C])
	)

Step-by-step explanation

Step 1: EVALUATE
EVALUATE returns the result of the table expression. In this query, the table expression is created using ROW.

Step 2: ROW
ROW creates a single-row table containing the results of the expressions provided inside it.

Step 3: COUNT(AvgTable[Col A])
The COUNT function counts the non-blank values present in AvgTable[Col A].

Step 4: COUNT(AvgTable[Col B])
Similarly, COUNT counts the non-blank values in AvgTable[Col B].

Step 5: COUNT(AvgTable[Col C])
This counts the non-blank values in AvgTable[Col C].

What will you get?

The query returns one row with three calculated values.
The exact numbers depend on the data available in your AvgTable.

Col A Col B Col C
Count of non-blank values Count of non-blank values Count of non-blank values
Key takeaway:
COUNT directly counts non-blank values from a column. It does not require a table iterator.

2. COUNTX Function

Now let us look at COUNTX. Unlike COUNT, COUNTX takes a table and an expression. It evaluates that expression for each row and counts the non-blank results.

Query

DAX Query
EVALUATE
	ROW(
		"Col C", COUNTX(AvgTable, COALESCE([Col C], 0))
	)

Step-by-step explanation

Step 1: EVALUATE
EVALUATE returns the result of the table expression created by ROW.

Step 2: ROW
ROW creates a single-row result and gives the calculated value the output name Col C.

Step 3: COUNTX(AvgTable, …)
COUNTX iterates through the rows of AvgTable. For every row, it evaluates the expression provided as its second argument.

Step 4: COALESCE([Col C], 0)
COALESCE returns the value of [Col C] when it is not blank. If [Col C] is blank, it returns 0.

Step 5: COUNTX counts the expression results
Because the expression uses COALESCE to replace blank values with 0, the expression produces a numeric result instead of a blank for those rows. Therefore, those rows are also counted by COUNTX.

Important:
This is a key difference from directly counting AvgTable[Col C]. With COUNTX, you are counting the result of the expression COALESCE([Col C], 0), not simply counting the original column values.

Understanding the expression

Expression
COALESCE([Col C], 0)

The expression can be understood as follows:

  1. If [Col C] contains a value, return that value.
  2. If [Col C] is blank, return 0.
  3. COUNTX then counts the non-blank results produced by this expression.

COUNT vs COUNTX

Feature COUNT COUNTX
Input A column A table and an expression
Evaluation Counts values directly from the column Evaluates an expression row by row
Blank handling Blank column values are not counted Depends on the result of the expression
Iterator No Yes
Example COUNT(AvgTable[Col C]) COUNTX(AvgTable, COALESCE([Col C], 0))

Why Does COALESCE Matter in COUNTX?

Consider a row where [Col C] is blank.

With a direct count such as COUNT(AvgTable[Col C]), that blank value is not counted.

But in the COUNTX query, the expression converts the blank value into 0:

Blank Replacement
COALESCE([Col C], 0)

The result is no longer blank. It is 0, and COUNTX counts that non-blank expression result.

Key takeaway:
When using an iterator such as COUNTX, always pay attention to the expression being evaluated. Functions such as COALESCE can change whether a row produces a blank or non-blank result.

Understanding the Two Queries Together

COUNT
COUNT(AvgTable[Col C])

Here, DAX directly examines AvgTable[Col C] and counts its non-blank values.

COUNTX
COUNTX(
	AvgTable,
	COALESCE([Col C], 0)
)

Here, DAX goes through AvgTable row by row, evaluates COALESCE([Col C], 0) for every row, and then counts the non-blank expression results.

📝 Practice Exercise

Using the same AvgTable, try creating a query that compares the following:

  • COUNT(AvgTable[Col C])
  • COUNTX(AvgTable, COALESCE([Col C], 0))

Observe whether the two counts are the same or different when Col C contains blank values.

Then experiment with another expression inside COUNTX and observe how the result changes.

Conclusion

In this article, we learned how COUNT and COUNTX work in DAX.

  • COUNT counts non-blank values directly from a column.
  • COUNTX iterates through a table and counts the non-blank results of an expression.
  • COALESCE can replace blank values with 0.
  • Because COUNTX counts the expression result, replacing blanks with zero can cause those rows to be counted.
  • The choice between COUNT and COUNTX depends on whether you need to count a column directly or count the result of a row-by-row expression.

Understanding the difference between aggregation functions such as COUNT and iterator functions such as COUNTX is an important foundation for writing more advanced DAX queries.


📥 Practice Data:
Download Practice Data Free

🎥 Prefer learning through video?
DAX YouTube Playlist