在 Power BI 中,提到排名计算,我们第一时间想到的是 RANKX 函数。长期以来,RANKX 函数一直是 Power BI 中排名计算的代名词。但是 RANKX 只在进行单级别排名计算时简单,它进行层次排名计算有两个挑战:
-
-
现在让我们转到 DAX 计算部分,新建一个矩阵视觉对象,在行上添加产品类别和产品子类别,在值上添加销售额。
接下来我们来创建一个销售额排名度量值,要求同时给出产品类别排名跟产品子类别排名在各自层次的排名。
使用以下 DAX 语句实现。
将排名度量值添加到矩阵上,层次排名计算成功。
要使用 RANKX 创建分层排名,必须将层次结构告知 DAX 引擎。有两种方法可以实现:
-
-
我们创建了两个独立的变量来存储产品类别和产品子类别销售额的排名。在 Return 部分,第一个 IF 语句确定当前上下文级别是否在产品子类别层次结构内。对于所有每个产品子类别行,该条件都将为 TRUE。一旦满足条件,就会传递 SubcategoryRank 变量。如果不满足第一个 IF 条件,会继续判断当前上下文级别是否在产品类别层次结构内,满足条件返回 CategoryRank 变量,否则为空。
但是使用 RANKX 进行分层排名存在问题。
当我们通过单击矩阵中的 +/- 图标手动扩展每个产品类别进入产品子类别级别时,排名是正确的。但是,如果用户单击矩阵中的“向下钻取”选项来扩展层次结构,还能正确计算吗?
如上所示,产品类别级别的排名不正确,技术和家具产品都显示排名为 2。
出现此问题的原因是筛选上下文无法正常运行。尽管 RANKX 是一个迭代器,并且有一个筛选上下文在起作用,但当使用向下钻取在层次结构中向下扩展一层时,它无法传播。因此,产品类别的筛选上下文不会传播。这意味着层次排名的第二个条件不满足。为了解决这个问题,我们将使用另一个函数 RANK。
RANK 是一个窗口函数,它根据指定的分区提供当前上下文中的排名。
请查看下面的 DAX 语句以及在矩阵中的结果。
矩阵中的结果。
无论怎么变换层次结构,使用 RANK 函数计算出的排名结果都是正确的。
使用 RANKX 和 RANK 函数可以有效地实现 Power BI 中的分层排名。但当涉及到层次排名时,RANKX 因为自身的一些性质会出现计算错误的情况,而 RANK 函数属于窗口函数,它在不同层次结构和外部过滤器之间的排名计算时表现更好。
关于 RANK 与 RANKX 函数的区别,参考:
Power BI DAX 窗口函数 RANK