Rank Values Within Groups in Power BI Using DAX: RANKX Guide

Rank Values Within Groups in Power BI, Ranking data is one of the most useful techniques in Power BI. Whether you’re comparing sales representatives, ranking products within categories, or identifying the top-performing players on different teams, a simple overall rank is often not enough.

What if you want to answer a more specific question?

β€œWhat is this value’s rank compared only with other values in the same group?”

That is where grouped ranking in DAX becomes extremely useful.

In this article, you’ll learn how to create a calculated column that ranks values independently within each group using the RANKX and FILTER functions.

What Is Grouped Ranking?

Imagine you have basketball player data containing three columns:

  • Player
  • Team
  • Points

You don’t want to rank every player together. Instead, you want each player to be compared only with players from the same team.

For example:

PlayerTeamPointsRank
AlexTeam A391
JohnTeam A302
DavidTeam A223
MikeTeam B451
SamTeam B282
TomTeam B173

Notice that Mike receives rank 1 even though his 45 points are being compared only with Team B players.

This is different from a normal ranking, where all players would compete against one another.

The DAX Formula for Rank Values Within Groups in Power BI

Suppose your Power BI table is called my_data.

You can create a calculated column using:

Points Rank = 
VAR current_team = 'my_data'[Team]
RETURN
    RANKX(
        FILTER(
            'my_data',
            'my_data'[Team] = current_team
        ),
        'my_data'[Points],
        ,
        ,
        SKIP
    )
πŸ”₯ HUGE DEALS ON BOOKS
πŸ“˜
DATA SCIENCE
Data Science: Big Data, Machine Learning, and More
πŸ”₯ HUGE DEAL
CHECK AMAZON OFFER β†’
🐍
PYTHON β€’ DATA SCIENCE
Python for Data Science
πŸ”₯ HUGE DEAL
CHECK AMAZON OFFER β†’
πŸ“Š
BUSINESS ANALYTICS
Business Analytics
πŸ”₯ HUGE DEAL
CHECK AMAZON OFFER β†’

This formula creates a new column called Points Rank and calculates the rank of each player’s points within their own team.

How Does the Formula Work?

At first glance, RANKX combined with FILTER can look complicated. However, the logic is straightforward.

Step 1: Capture the Current Group

VAR current_team = 'my_data'[Team]

The variable stores the team associated with the current row.

For example, if the current player belongs to Team A, then:

current_team = "Team A"

This gives DAX the group against which the current row should be compared.

Step 2: Filter the Table

The next part is:

FILTER(
    'my_data',
    'my_data'[Team] = current_team
)

This tells Power BI to create a temporary table containing only rows belonging to the current team.

If the current player is from Team A, the ranking calculation sees only Team A players.

Conceptually:

All Players
     ↓
Filter by Current Team
     ↓
Team A Players
     ↓
Rank Their Points

This is the key idea behind grouped ranking.

Step 3: Rank the Values with RANKX

The RANKX function performs the actual ranking:

RANKX(
    FILTER(...),
    'my_data'[Points],
    ,
    ,
    SKIP
)

The first argument defines the table to rank.

The second argument specifies the value being ranked:

'my_data'[Points]

The final argument:

SKIP

defines how ties should be handled.

Understanding the Ranking Direction

One important detail in RANKX is the order parameter.

By default, RANKX ranks values in descending order.

That means:

  • Highest value β†’ Rank 1
  • Second-highest β†’ Rank 2
  • Third-highest β†’ Rank 3

For example:

PlayerTeamPointsRank
AlexA391
JohnA302
DavidA223

This is usually what you want when ranking performance, sales, scores, revenue, or similar metrics.

Ranking from Lowest to Highest

Sometimes you need the opposite approach.

For example, you might want to rank employees according to the lowest number of defects, lowest processing time, or lowest cost.

In that case, specify 1 as the fourth argument of RANKX:

Points Rank = 
VAR current_team = 'my_data'[Team]
RETURN
    RANKX(
        FILTER(
            'my_data',
            'my_data'[Team] = current_team
        ),
        'my_data'[Points],
        ,
        1,
        SKIP
    )

Now the smallest value receives rank 1.

For example:

PlayerTeamPointsRank
DavidA221
JohnA302
AlexA393

So remember:

RANKX order = DESC β†’ highest value gets Rank 1
RANKX order = ASC  β†’ lowest value gets Rank 1

What Does SKIP Mean?

The final parameter controls how DAX handles tied values.

Consider this example:

PlayerTeamPoints
AlexA40
JohnA30
DavidA30
PeterA20

With SKIP, the result is:

PlayerPointsRank
Alex401
John302
David302
Peter204

Notice that there is no rank 3.

This happens because two players share rank 2, so the next available position is rank 4.

If you want different tie behavior, DENSE can be used instead:

Points Rank = 
VAR current_team = 'my_data'[Team]
RETURN
    RANKX(
        FILTER(
            'my_data',
            'my_data'[Team] = current_team
        ),
        'my_data'[Points],
        ,
        ,
        DENSE
    )

With DENSE, the same example would produce:

PlayerPointsRank
Alex401
John302
David302
Peter203

There is no skipped rank.

How to Create the Calculated Column in Power BI

To implement this in Power BI Desktop:

  1. Open your Power BI report.
  2. Select the table containing your data.
  3. Go to Table tools.
  4. Select New column.
  5. Enter the DAX formula.
  6. Press Enter.
  7. Power BI will create the ranking column.

For example:

Points Rank = 
VAR current_team = 'my_data'[Team]
RETURN
    RANKX(
        FILTER(
            'my_data',
            'my_data'[Team] = current_team
        ),
        'my_data'[Points],
        ,
        ,
        SKIP
    )

You can then add Player, Team, Points, and Points Rank to a table visual to verify the results.

A Practical Example Beyond Basketball

Grouped ranking isn’t limited to sports data.

Suppose you’re analyzing company sales:

SalespersonRegionSales
ANorth500000
BNorth420000
CNorth350000
DSouth600000
ESouth450000
FSouth300000

You could use the same technique to determine the salesperson’s position within their region.

Simply replace the columns:

Sales Rank = 
VAR current_region = 'my_data'[Region]
RETURN
    RANKX(
        FILTER(
            'my_data',
            'my_data'[Region] = current_region
        ),
        'my_data'[Sales],
        ,
        ,
        SKIP
    )

The same pattern can be applied to:

  • Sales by region
  • Products by category
  • Employees by department
  • Students by class
  • Customers by country
  • Stores by territory
  • Products by brand
  • Revenue by business unit
  • Performance by team

The General Pattern to Remember

The most important concept is not the basketball example. It is the reusable DAX pattern:

Rank =
VAR current_group = 'Table'[GroupColumn]
RETURN
    RANKX(
        FILTER(
            'Table',
            'Table'[GroupColumn] = current_group
        ),
        'Table'[ValueColumn],
        ,
        ,
        SKIP
    )

You can think of it as:

Identify the current group β†’ filter to that group β†’ rank the desired value.

Once you understand this pattern, you can adapt it to almost any grouped-ranking problem in Power BI.

Final Takeaway

A standard rank tells you where a value stands across the entire dataset. A grouped rank tells you where that value stands among comparable records.

The combination of VAR, FILTER, and RANKX provides a simple way to achieve this in DAX.

If you need the highest value to receive rank 1, use the default descending order. If you need the lowest value to receive rank 1, use 1 as the order argument. And if your data contains ties, choose between SKIP and DENSE depending on whether you want ranking positions to be skipped.

Once you master this technique, you can build more meaningful Power BI reports where every employee, product, customer, or business unit is evaluated within the group that actually matters.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

two × four =