Business Professionals
Power BI | Power Pivot | Power Query | DAX
Cloud Flows | RPA | AI Builder | Copilot
60+ Formulas | Data Stories | Advanced Reporting & Modeling
VB Programming | Report Automation |
MS-Office Automation
Techno-Business Professionals
Power BI | Power Query | Advanced DAX | SQL - Query &
Programming
Microsoft Fabric | Power BI | Power Query | Advanced DAX |
SQL - Query & Programming
Power BI | Power Apps | Power Automate | Copilot Studio | Power Pages | Dataverse
Microsoft Power Apps | Microsoft Power Automate
Power BI | Adv. DAX | SQL (Query & Programming) |
VBA | Python | Web Scrapping | API Integration
Power BI | Power Apps | Power Automate |
SQL (Query & Programming)
Power BI | Adv. DAX | Power Apps | Power Automate |
SQL (Query & Programming) | VBA | Python | Web Scrapping | API Integration
Power Apps | Power Automate | SQL | VBA | Python |
Web Scraping | RPA | API Integration
Technology Professionals
Power BI | DAX | SQL | ETL with SSIS | SSAS | VBA | Python
Power BI | SQL | Azure Data Lake | Synapse Analytics |
Data Factory | Databricks | Power Apps | Power Automate |
Azure Analysis Services
Microsoft Fabric | Power BI | SQL | Lakehouse |
Data Factory (Pipelines) | Dataflows Gen2 | KQL | Delta Tables | Power Apps | Power Automate
Power BI | Power Apps | Power Automate | SQL | VBA | Python | API Integration
Power BI | Advanced DAX | Databricks | SQL | Lakehouse Architecture
Business Professionals
Power BI | Power Pivot | Power Query | DAX
Cloud Flows | RPA | AI Builder | Copilot
60+ Formulas | Data Stories | Advanced Reporting & Modeling
VB Programming | Report Automation |
MS-Office Automation
Techno-Business Professionals
Power BI | Power Query | Advanced DAX | SQL - Query &
Programming
Microsoft Fabric | Power BI | Power Query | Advanced DAX |
SQL - Query & Programming
Power BI | Power Apps | Power Automate | Copilot Studio | Power Pages | Dataverse
Microsoft Power Apps | Microsoft Power Automate
Power BI | Adv. DAX | SQL (Query & Programming) |
VBA | Web Scrapping | API Integration
Power BI | Power Apps | Power Automate |
SQL (Query & Programming)
Power BI | Adv. DAX | Power Apps | Power Automate |
SQL (Query & Programming) | VBA | Web Scrapping | API Integration
Power Apps | Power Automate | SQL | VBA |
Web Scraping | RPA | API Integration
Technology Professionals
Power BI | DAX | SQL | ETL with SSIS | SSAS | VBA
Power BI | SQL | Azure Data Lake | Synapse Analytics |
Data Factory | Azure Analysis Services
Microsoft Fabric | Power BI | SQL | Lakehouse |
Data Factory (Pipelines) | Dataflows Gen2 | KQL | Delta Tables
Power BI | Power Apps | Power Automate | SQL | VBA | API Integration
Power BI | Advanced DAX | Databricks | SQL | Lakehouse Architecture
Your matrix looks perfect at the row level, but the grand total is nonsense. Sales per customer are fine, yet the total shows a number nobody can reconcile. You tweak formats, refresh, even re‑import the data – the total is still wrong. This article shows why that happens in DAX, how to fix it properly, and how to design measures that never break totals again.
You’re building a Power BI report for a sales team:
Sales (one row per order line)Customers, Products, CalendarCustomer[Customer Name] on rows and a custom measure for margin % in valuesThe team wants a margin percentage that:
You write this measure:
Margin % (wrong) =
VAR NetSales =
CALCULATE(
SUM ( Sales[NetAmount] ),
Sales[IsTestOrder] = FALSE,
Sales[IsSample] = FALSE
)
VAR NetCost =
CALCULATE(
SUM ( Sales[CostAmount] ),
Sales[IsTestOrder] = FALSE,
Sales[IsSample] = FALSE
)
RETURN
DIVIDE ( NetSales - NetCost, NetSales )
Row‑level values look right. But the total margin % at the bottom of the matrix doesn’t match the finance team’s number from their SQL query, even though they’re using the same filters.
The numbers in each row are correct; the grand total is wrong.
The key point: a measure is not aggregated from its row values. Power BI does not add up the visible numbers to get the total. It re‑evaluates the measure once in the total row’s filter context.
In the matrix:
Customer[Customer Name] = X, plus any slicers/page filters.So Margin % (wrong) is evaluated:
Sales.Sales (subject to slicers), with no customer filter.That behaviour is correct DAX. The problem is the measure design.
In our scenario, the matrix is showing:
Margin % (wrong) evaluated per customerMargin % (wrong) evaluated over all customersIf the team expects the total to be:
Sum of NetMargin / Sum of NetSales (over all customers)
…then the measure is fine; DAX already does that.
But what people often expect (without realising) is:
Weighted average of the visible customer margin % values
Those two are only the same if each customer has the same NetSales. In real data, they differ. The visual shows the correct ratio over the total filter context, but the team is mentally aggregating the row‑level ratios.
This is the core of "why your Power BI total is wrong":
The more subtle mistake appears when you use iterators (SUMX, AVERAGEX, etc.) with row context and then expect totals to behave like simple sums.
Consider a more complex version of the same measure, where you try to pre‑calculate margin per order:
Margin % per Order (wrong) =
VAR Orders =
FILTER (
Sales,
Sales[IsTestOrder] = FALSE
&& Sales[IsSample] = FALSE
)
VAR MarginPerOrder =
ADDCOLUMNS (
Orders,
"OrderMargin", Sales[NetAmount] - Sales[CostAmount],
"OrderMarginPct",
DIVIDE ( Sales[NetAmount] - Sales[CostAmount], Sales[NetAmount] )
)
RETURN
AVERAGEX ( MarginPerOrder, [OrderMarginPct] )
This measure:
At the customer level, this might match what the team expects. At the total level, it becomes the average of all order‑line margins across all customers. If finance expects the total margin % to be based on total margin / total sales, this total is wrong.
The mistake:
The most reliable pattern to avoid broken totals is:
Net Sales =
CALCULATE (
SUM ( Sales[NetAmount] ),
Sales[IsTestOrder] = FALSE,
Sales[IsSample] = FALSE
)
Net Cost =
CALCULATE (
SUM ( Sales[CostAmount] ),
Sales[IsTestOrder] = FALSE,
Sales[IsSample] = FALSE
)
Net Margin =
[Net Sales] - [Net Cost]
These measures:
Margin % =
DIVIDE ( [Net Margin], [Net Sales] )
Now:
[Margin %] is customer margin / customer sales.[Margin %] is total margin / total sales.The total is not the average of customer margin %, it is the ratio over the total filter context – which is what finance usually expects.
If the business really wants the average of customer margins (each customer weighted equally), you can define that explicitly:
Margin % (avg customers) =
VAR CustomerTable =
VALUES ( Customer[Customer ID] )
VAR CustomerMarginTable =
ADDCOLUMNS (
CustomerTable,
"CustomerMarginPct",
VAR CustomerNetSales = CALCULATE ( [Net Sales] )
VAR CustomerNetMargin = CALCULATE ( [Net Margin] )
RETURN DIVIDE ( CustomerNetMargin, CustomerNetSales )
)
RETURN
AVERAGEX ( CustomerMarginTable, [CustomerMarginPct] )
This measure:
Margin % when customer sizes vary.The important part is that the measure’s definition matches the business expectation.
Once you understand that totals are re‑evaluated, not summed, several other "wrong total" patterns make sense.
Using ALL or REMOVEFILTERS without care can make totals look detached from the matrix.
Example:
Sales % of All Customers =
DIVIDE (
[Net Sales],
CALCULATE ( [Net Sales], ALL ( Customer ) )
)
Behaviour:
If someone expects the total to show "sum of the row percentages", they will call this a wrong total. But the measure is doing exactly what it says.
Fix is not technical; it’s about naming and expectation:
Sales % of All Customers.If the requirement is "percentage of visible customers", then change the denominator:
Sales % of Visible Customers =
VAR VisibleCustomerSales = [Net Sales]
VAR VisibleTotalSales =
CALCULATE ( [Net Sales], ALLSELECTED ( Customer ) )
RETURN
DIVIDE ( VisibleCustomerSales, VisibleTotalSales )
ALLSELECTED respects slicers and outer visuals, so the total matches the sum of row percentages.
Another pattern:
High Margin Orders Count (wrong) =
COUNTROWS (
FILTER (
Sales,
Sales[IsTestOrder] = FALSE
&& Sales[Margin] > 0.3
)
)
This measure counts orders with margin > 30% ignoring any existing filter on Sales[Margin] coming from the visual. It also ignores any dimension filters that don’t propagate, depending on relationships.
Per customer, this might look reasonable. In the total, it often surprises people because it counts orders they don’t think are "in the report".
A safer pattern is to apply conditions on top of the current filter context rather than replacing it completely:
High Margin Orders Count =
CALCULATE (
COUNTROWS ( Sales ),
Sales[IsTestOrder] = FALSE,
Sales[Margin] > 0.3
)
Here, existing filters (customer, date, product) remain in effect for both rows and totals.
Back to the sales team scenario. To make the report robust and shareable, you want a pattern that:
Create a measure table (e.g. Measures) and put all measures there. This doesn’t change behaviour but makes it easier to:
[Net Sales], [Net Cost], [Net Margin][Margin %], [Sales % of All Customers], etc.[Margin % (avg customers)], scenario‑specific logicBuild a simple matrix for validation:
Customer[Customer Name][Net Sales], [Net Margin], [Margin %], [Margin % (avg customers)]Check:
[Net Sales] match the source system?[Margin %] at the total match TotalMargin / TotalSales from SQL or Excel?[Margin % (avg customers)] match the average of visible row margin % values?This matrix becomes your "DAX contract" with stakeholders. Once they agree on which measure corresponds to which business question, disputes about totals drop sharply.
To make this concrete for your team, build and share a .pbix with:
Sales table (import mode) with columns:
OrderID (text or integer)CustomerIDNetAmountCostAmountIsTestOrder (TRUE/FALSE)IsSample (TRUE/FALSE)Customer dimension with CustomerID, Customer Name.Sales[CustomerID] → Customer[CustomerID] (single, one‑to‑many).Net SalesNet CostNet MarginMargin %Margin % (avg customers)Sales % of All CustomersSales % of Visible CustomersThis file becomes your reference implementation of "totals‑safe" measures. When someone reports a new "wrong total" in another report, you can compare their measure pattern against this file and usually spot the issue quickly.
Whenever a total looks wrong, don’t start by checking the visual – start by reading the measure. If you can’t explain what the measure is supposed to mean at the grand‑total filter context, redesign it using base measures and explicit aggregation until the total is a direct, obvious consequence of the business logic.
This article reflects how experienced Power BI teams are standardising DAX measure patterns to avoid confusing totals, especially in shared semantic models and multi-report environments where business logic must stay consistent across visuals.
Professionals who want to apply these patterns to their own data can explore Excelgoodies' Power BI Reporting programme - taught live by instructors, with certification awarded once a real project is running at work.
Insights compiled through ongoing industry research and discussions within the Excelgoodies Analytics Community.
Power BI
New
Next Batches Now Live
Power BI
SQL
Power Apps
Power Automate
Microsoft Fabrics
Azure Data Engineering