DAX and data models
How to Use the RANKX Function in Power BI
RANKX ranks items by a measure and updates as filters change. The syntax, how ties are handled, and when to use ALL versus ALLSELECTED, with DAX examples.
Sajagan Thirugnanam
·
Updated
RANKX is the DAX function that assigns a rank, such as 1st or 2nd, to each item in a table based on a measure or expression, and it recalculates automatically as filters and slicers change. The syntax is RANKX(<table>, <expression>, [<value>], [<order>], [<ties>]). This guide covers the syntax, the difference between ranking with ALL and ALLSELECTED, and how ties are handled.
RANKX syntax
RANKX(<table>, <expression>, [<value>], [<order>], [<ties>table: the set of items to rank, for example all products.expression: the measure or expression to rank by, for example a Total Sales measure.value(optional): the expression to evaluate for the current row. Leave this blank in most cases; Power BI infers it from the row context.order(optional):DESC(default) ranks the highest value 1st.ASCranks the lowest value 1st.ties(optional): how tied values are ranked.SKIPis the default.
A basic ranking measure
Assume you have a Sales table, a Products table, and this base measure:
Total Sales = SUM(Sales[SalesAmount])To rank products by sales:
Product Rank = RANKX(ALL(Products[ProductName]), [Total Sales], , DESC)This ranks every product by total sales, highest first, and the third argument is left blank so Power BI evaluates the current row automatically.
Why ALL matters inside RANKX
Writing RANKX(Products, [Total Sales]) without a filter modifier ranks only the products visible in the visual, not every product in the model. If a report is filtered to one region, a product ranks against only the other products in that region, not the whole table. That can look like a bug when it is actually the filter context doing what it always does.
ALL() and ALLSELECTED() fix this by controlling which rows RANKX ranks against, independent of the filter context around it.
RANKX with ALL versus ALLSELECTED
Rank across the full dataset, ignoring filters:
Rank Global = RANKX(ALL(Products[ProductName]), [Total Sales], , DESC)This rank never changes with slicers. A product filtered to one region still shows its rank across every region.
Rank only within the current selection:
Rank Selected = RANKX(ALLSELECTED(Products[ProductName]), [Total Sales], , DESC)If a reader selects a region in a slicer, ranking recalculates within that selection only. This is usually what a dashboard needs.
Use ALL for a fixed benchmark rank that should not move with filters. Use ALLSELECTED for a "Top N in what is shown" rank that follows slicers. Our row context vs filter context guide covers why ALL and ALLSELECTED behave differently, and our ALLSELECTED vs ALL guide covers the distinction in more depth.
Ranking by a different measure
The expression argument can be any measure, so the same pattern ranks by profit instead of sales:
Total Profit = SUM(Sales[Profit])
Profit Rank = RANKX(ALL(Products[ProductName]), [Total Profit], , DESC)Ranking in ascending order
To rank the lowest value 1st, for example to find the lowest-profit products, set the order argument to ASC:
Lowest Profit Rank = RANKX(ALL(Products[ProductName]), [Total Profit], , ASC)Handling ties
Consider four products with these sales totals:
Product | Sales |
|---|---|
A | 100 |
B | 90 |
C | 90 |
D | 70 |
SKIP (the default)
Product Rank = RANKX(ALL(Products[ProductName]), [Total Sales], , DESC)B and C tie at 90 and both get rank 2. D gets rank 4: rank 3 is skipped to account for the tie.
A = 1
B = 2
C = 2
D = 4
DENSE
Product Rank Dense = RANKX(ALL(Products[ProductName]), [Total Sales], , DESC, DENSE)B and C still tie at rank 2, but D gets rank 3. No rank number is skipped.
A = 1
B = 2
C = 2
D = 3
Both are correct DAX; they answer different questions. SKIP reflects true position, useful for sports-style leaderboards where a gap after a tie is expected. DENSE gives a compact 1-2-3 sequence, useful when you filter a visual to "rank <= 3" and want exactly three distinct rank values to show.
RANKX and filter context
RANKX ranks within whatever filter context it runs in. If a report is filtered to one region, RANKX ranks only the rows that remain after that filter, unless ALL overrides it. This is the same filter context mechanism that governs every DAX measure. Our complete DAX guide covers filter context from the ground up if RANKX's behavior here is unfamiliar.
FAQs
What does RANKX do in Power BI?
RANKX assigns a rank number to each row of a table based on a measure or expression, and it recalculates dynamically as filters and slicers change.
How do I rank within a slicer selection?
Wrap the ranking table in ALLSELECTED() instead of ALL(). RANKX(ALLSELECTED(Products[ProductName]), [Total Sales], , DESC) ranks only the rows visible after the current slicer selection.
What is dense ranking in Power BI?
Dense ranking means tied values share a rank and the next rank number is not skipped, for example 1, 2, 2, 3. Set the fifth argument of RANKX to DENSE to use it; the default, SKIP, would rank the same values 1, 2, 2, 4.
Sources
RANKX function (DAX) - Microsoft Learn
RANKX is the DAX function that assigns a rank, such as 1st or 2nd, to each item in a table based on a measure or expression, and it recalculates automatically as filters and slicers change. The syntax is RANKX(<table>, <expression>, [<value>], [<order>], [<ties>]). This guide covers the syntax, the difference between ranking with ALL and ALLSELECTED, and how ties are handled.
RANKX syntax
RANKX(<table>, <expression>, [<value>], [<order>], [<ties>table: the set of items to rank, for example all products.expression: the measure or expression to rank by, for example a Total Sales measure.value(optional): the expression to evaluate for the current row. Leave this blank in most cases; Power BI infers it from the row context.order(optional):DESC(default) ranks the highest value 1st.ASCranks the lowest value 1st.ties(optional): how tied values are ranked.SKIPis the default.
A basic ranking measure
Assume you have a Sales table, a Products table, and this base measure:
Total Sales = SUM(Sales[SalesAmount])To rank products by sales:
Product Rank = RANKX(ALL(Products[ProductName]), [Total Sales], , DESC)This ranks every product by total sales, highest first, and the third argument is left blank so Power BI evaluates the current row automatically.
Why ALL matters inside RANKX
Writing RANKX(Products, [Total Sales]) without a filter modifier ranks only the products visible in the visual, not every product in the model. If a report is filtered to one region, a product ranks against only the other products in that region, not the whole table. That can look like a bug when it is actually the filter context doing what it always does.
ALL() and ALLSELECTED() fix this by controlling which rows RANKX ranks against, independent of the filter context around it.
RANKX with ALL versus ALLSELECTED
Rank across the full dataset, ignoring filters:
Rank Global = RANKX(ALL(Products[ProductName]), [Total Sales], , DESC)This rank never changes with slicers. A product filtered to one region still shows its rank across every region.
Rank only within the current selection:
Rank Selected = RANKX(ALLSELECTED(Products[ProductName]), [Total Sales], , DESC)If a reader selects a region in a slicer, ranking recalculates within that selection only. This is usually what a dashboard needs.
Use ALL for a fixed benchmark rank that should not move with filters. Use ALLSELECTED for a "Top N in what is shown" rank that follows slicers. Our row context vs filter context guide covers why ALL and ALLSELECTED behave differently, and our ALLSELECTED vs ALL guide covers the distinction in more depth.
Ranking by a different measure
The expression argument can be any measure, so the same pattern ranks by profit instead of sales:
Total Profit = SUM(Sales[Profit])
Profit Rank = RANKX(ALL(Products[ProductName]), [Total Profit], , DESC)Ranking in ascending order
To rank the lowest value 1st, for example to find the lowest-profit products, set the order argument to ASC:
Lowest Profit Rank = RANKX(ALL(Products[ProductName]), [Total Profit], , ASC)Handling ties
Consider four products with these sales totals:
Product | Sales |
|---|---|
A | 100 |
B | 90 |
C | 90 |
D | 70 |
SKIP (the default)
Product Rank = RANKX(ALL(Products[ProductName]), [Total Sales], , DESC)B and C tie at 90 and both get rank 2. D gets rank 4: rank 3 is skipped to account for the tie.
A = 1
B = 2
C = 2
D = 4
DENSE
Product Rank Dense = RANKX(ALL(Products[ProductName]), [Total Sales], , DESC, DENSE)B and C still tie at rank 2, but D gets rank 3. No rank number is skipped.
A = 1
B = 2
C = 2
D = 3
Both are correct DAX; they answer different questions. SKIP reflects true position, useful for sports-style leaderboards where a gap after a tie is expected. DENSE gives a compact 1-2-3 sequence, useful when you filter a visual to "rank <= 3" and want exactly three distinct rank values to show.
RANKX and filter context
RANKX ranks within whatever filter context it runs in. If a report is filtered to one region, RANKX ranks only the rows that remain after that filter, unless ALL overrides it. This is the same filter context mechanism that governs every DAX measure. Our complete DAX guide covers filter context from the ground up if RANKX's behavior here is unfamiliar.
FAQs
What does RANKX do in Power BI?
RANKX assigns a rank number to each row of a table based on a measure or expression, and it recalculates dynamically as filters and slicers change.
How do I rank within a slicer selection?
Wrap the ranking table in ALLSELECTED() instead of ALL(). RANKX(ALLSELECTED(Products[ProductName]), [Total Sales], , DESC) ranks only the rows visible after the current slicer selection.
What is dense ranking in Power BI?
Dense ranking means tied values share a rank and the next rank number is not skipped, for example 1, 2, 2, 3. Set the fifth argument of RANKX to DENSE to use it; the default, SKIP, would rank the same values 1, 2, 2, 4.
Sources
RANKX function (DAX) - Microsoft Learn
Show us the report nobody trusts.
1 · A 30-minute call.
2 · We look at your current reports together.
3 · We tell you what we would do.
Show us the report nobody trusts.
1 · A 30-minute call.
2 · We look at your current reports together.
3 · We tell you what we would do.
Show us the report nobody trusts.
1 · A 30-minute call.
2 · We look at your current reports together.
3 · We tell you what we would do.
CaseWhen is a Berlin BI consultancy that builds reporting that leaders can trust, on the Microsoft stack: Power BI, Fabric and Azure.
Berlin, Germany
Free tools
CaseWhen is a Berlin BI consultancy that builds reporting that leaders can trust, on the Microsoft stack: Power BI, Fabric and Azure.
Berlin, Germany
Free tools
CaseWhen is a Berlin BI consultancy that builds reporting that leaders can trust, on the Microsoft stack: Power BI, Fabric and Azure.
Berlin, Germany
