前天的文章《那么多关于RANKX函数排名的方法,竟然都是错的!| DAX大坑》里提到,RANKX ALLSELECTED函数的使用,只是在特定的条件下才是正确的,显然,这里的问题就是出在ALLSELECTED身上。
那么,ALLSELECTED函数的问题提到底在哪里?
我们首先来看一个最常见的使用ALLSELECTED函数的分组占比问题——DAX圣经里也是用同样的例子。
三个简单度量如下:
代码语言:javascript复制总数量:=SUM('表1'[数量])
代码语言:javascript复制总数量_allselected:=
SUMX(
ALLSELECTED('表1'[产品]),
[总数量]
)
代码语言:javascript复制占比:=DIVIDE([总数量],[总数量_allselected])
放在透视表里结果如下:
这个问题看似很简单,通过ALLSELECTED函数得到结果看起来也很“容易理解”:对每个分组的所有子类别(产品)求和。
但是,误解由此开始:很多人就因此理解为,ALLSELECTED函数返回了当前组下的所有子类别(产品)内容!
比如,上面大海下面的:DAX、M和Power BI;小勤下的:超级表、数据透视和Power BI。
但是,这种理解是错的!
ALLSELECTED返回的其实是所有产品类别,无论是在大海组下,还是在小勤组下!
我们算一下它的内容数量即可:
放到透视表里:
那问题来了,为什么算总数和算比例的时候都是对的?
其实,只是因为,在每个组下不存在的项目,因为受到这个组筛选器的影响,计算得到的结果为blank,所以不会体现出来。
然后,我们再回头看RANKX那个例子就明白了,为什么在升序排名会出现错误的结果!因为计算为空的内容隐藏掉了:
存在负数的排名错误也是同样的道理:
实际上,ALLSELECTED是个非常,非常,非常复杂的函数,以至于,我一般不建议大家去使用它!而且,对于这些常见的使用ALLSELECTED函数的场景,我们有更加通用、精确的方法来实现——
这就是我后面要继续分享的内容:
- 理解和应用CALCULATETABLE函数
- RANKX排名原理及精确控制方法
- ……