Skip to content

QueryAndChart.

Power BI running total and category rank in DAX, with no helper columns

Checked 10 November 2026 · Verification: Python 3.12.3, pandas 2.1.4 · 9-minute read

Two of the most-asked DAX questions have the same answer shape: change the filter context, then aggregate. A running total sums everything up to the current month. A rank compares one category's total against every visible category's total. Both are one measure each, both work with slicers, and neither needs a helper column. The headline result: the 2025 running total reaches $122,707.17 by October, and Desks ranks first among the three categories at $56,958.60.

Key result: 2025 running total at October: $122,707.17. Category rank, January–October 2025: 1. Desks $56,958.60 · 2. Chairs $41,516.59 · 3. Lamps $24,231.98.

Download the data and the measures: the sales file (CSV) (66 rows, MD5 51a16fd9e023dd0208564a0c2c1a089e) and the measures file (DAX) (the three measures below, ready to paste). The data is a constructed sample — three product lines, monthly revenue from January 2024 to October 2025 — not a real company's sales. It is the same file as the year-over-year guide, so the two guides build on one model.

Line chart of the 2025 running total rising from $11,543 in January to $122,707 in October, with grey bars showing each month's revenue underneath.
2025 running total (line) over monthly revenue (bars). The chart is drawn from the computed values in the check table below.

What you need

1. Import the sales file

In Power BI Desktop, go to Home > Get data > Text/CSV, pick the sales file, and choose Load. Check the column types after loading: Month must be a date, Revenue a decimal number. If Month loads as text, the relationship in step 3 will not work — change the type in Power Query first.

2. Build the calendar table

The running total filters on dates, so it needs the same continuous date table as any time-based measure. Microsoft's documentation says to mark one of the tables containing a date column as the date table before using time-intelligence functions (Microsoft Learn: Set and use date tables in Power BI Desktop). Create it as a calculated table:

Modeling > New table

Calendar =
CALENDAR ( DATE ( 2024, 1, 1 ), DATE ( 2025, 12, 31 ) )

Then mark it: select the Calendar table in the Fields pane, right-click, and choose Mark as date table > Mark as date table, with Date as the date column. The range must cover every month in the sales file.

3. Relate the two tables

In Model view, drag Calendar[Date] onto Sales[Month]. The relationship is one-to-many, single direction, from Calendar to Sales. The running total in step 4 filters the calendar side, so this relationship is what lets it reach the sales rows.

4. Write the three measures

Create each measure on the Sales table (Modeling > New measure). The measures file (DAX) holds the same three measures, ready to paste.

Total Sales = SUM ( Sales[Revenue] )

Running Total Sales =
CALCULATE (
    [Total Sales],
    FILTER (
        ALLSELECTED ( Calendar[Date] ),
        Calendar[Date] <= MAX ( Calendar[Date] )
    )
)

Category Rank =
RANKX (
    ALLSELECTED ( Sales[Category] ),
    [Total Sales],
    ,
    DESC,
    SKIP
)

How the running total works: CALCULATE evaluates an expression in a modified filter context (Microsoft Learn, CALCULATE function (DAX)). Here the modification is a FILTER over ALLSELECTED ( Calendar[Date] ) — every date the slicers leave visible — keeping only dates up to the current row's date, which MAX ( Calendar[Date] ) supplies. The sum then covers January through the current month. ALLSELECTED matters: it keeps slicer filters, so filtering the report to 2025 restarts the running total at January 2025 instead of carrying 2024 with it (Microsoft Learn, ALLSELECTED function (DAX)).

How the rank works: RANKX returns the ranking of a number in a list of numbers for each row in the table argument (Microsoft Learn, RANKX function (DAX)). The table here is ALLSELECTED ( Sales[Category] ) — the visible categories — and the expression is [Total Sales], evaluated once per category. DESC puts the largest total at rank 1; SKIP means tied categories share a rank and the next rank is skipped (1, 1, 3), the usual leaderboard behaviour.

5. Put them in visuals

For the running total, add a line chart with Calendar[Date] (month level) on the x-axis and [Running Total Sales] as the value. Add [Total Sales] as a second series if you want the monthly bars underneath the line, as in the chart above. For the rank, add a table visual with Sales[Category], [Total Sales], and [Category Rank], sorted by rank ascending. Add a year slicer on Calendar[Date] and set it to 2025: the running total restarts at January, and the rank recomputes over the filtered year.

6. Check the numbers

Put Calendar[Date] (month level), [Total Sales], and [Running Total Sales] in a table visual, filtered to 2025. Every row must match this table, which was computed independently from the same CSV:

MonthTotal Sales ($)Running Total ($)
January 202511,542.5711,542.57
February 20259,571.4721,114.04
March 202512,194.2533,308.29
April 202512,329.8345,638.12
May 202512,556.4258,194.54
June 202512,196.7070,391.24
July 202512,184.2282,575.46
August 202513,279.9995,855.45
September 202513,415.30109,270.75
October 202513,436.42122,707.17

And the rank table, filtered to January–October 2025, must read:

RankCategoryTotal Sales ($)
1Desks56,958.60
2Chairs41,516.59
3Lamps24,231.98

If the running total equals the month's sales on every row, the FILTER is not reaching the calendar — check the relationship in step 3. If every category ranks 1, the RANKX table argument is wrong — see the first trap below.

Traps

TRAP — RANKING THE FACT TABLE RANKS EVERY ROW. RANKX ( Sales, [Total Sales] ) ranks each of the 66 sales rows against the other 65, so the table visual shows ranks up to 66 and the category totals are meaningless. Rank over the dimension you are comparing — here ALLSELECTED ( Sales[Category] ) — so the expression is evaluated once per category, not once per row.

TRAP — ALL IGNORES THE SLICER, ALLSELECTED DOES NOT. Using ALL ( Sales[Category] ) in the rank keeps categories the slicer removed in the ranking, so a category filtered out of the visual still takes a rank slot. ALLSELECTED ranks only what is visible. The same applies to the running total: ALL would carry 2024 into a 2025-filtered chart.

TRAP — A RUNNING TOTAL NEEDS THE DATE, NOT THE MONTH NAME. Filtering on a text month name (“October”) sorts alphabetically and the <= comparison is meaningless. The comparison in this measure runs on Calendar[Date], a real date column — which is why the calendar table exists at all.

End state

A line chart that climbs from $11,542.57 in January to $122,707.17 in October 2025, and a three-row rank table with Desks first. Both measures respect slicers: filter to a single quarter and the running total restarts at that quarter's first month while the rank recomputes over the visible categories. The same two patterns — CALCULATE with a date-bounded FILTER, and RANKX over ALLSELECTED — cover most cumulative and leaderboard reporting.

Sources

Verified 10 November 2026. The running totals and ranks in the check tables were computed in Python 3.12.3 with pandas 2.1.4 by cumulative-summing the same sales file by month and ranking category totals for January–October 2025 — the identical aggregations the DAX performs. Running total at October 2025: $122,707.17. Ranks: Desks 1 ($56,958.60), Chairs 2 ($41,516.59), and Lamps 3 ($24,231.98). The Power BI Desktop interface steps (import, calendar table, relationship, and visuals) were documented from Microsoft Learn and were not run on this machine: Power BI Desktop is Windows-only and is not installed here. Run the check tables against your own report; if a row disagrees, the model differs from the one described above.