Power BI之DAX神功:第2卷第5回 RankX函数前两个参数的秘密
关于RankX函数在《孙兴华讲PowerBI火力全开》笔记第25课做过详细讲解,今天我们只聊原理。
假设有这样一张表:

我们先来计算一个ABC三个商品的降序排名:
【度量值】总销售 = Sum(Sheet1[销售])
【度量值】排名1 = RANKX(ALL(Sheet1),[总销售])
【度量值】排名2 = RANKX(ALL(Sheet1[商品]),[总销售])

工作原理:
【度量值】排名1 = RANKX(ALL(Sheet1),[总销售])

【度量值】排名2 = RANKX(ALL(Sheet1[商品]),[总销售])

在这个案例上,度量值【排名1】和【排名2】我们并没有看出区别,那我们换一个案例:

在之前的课程中,我们提到ALL函数在Calculate里面是调节器,在Filter(ALL)、ankx(ALL) 等迭代函数中的第1参数中,它是表函数。
既然是表函数,就在新建表中测试一下,这是《孙兴华讲PowerBI火力全开》经典语句。


你会发现ALL函数跟我们的Values函数很相似,
ALL(表)和Values(表)都是复制这张表
ALL(列)和Values(列)都是返回这列去重后的单列表
那能不能用Values呢?不行!
为什么?你还记得吗?
ALL(表) 指这张表中所有列都不能筛选
ALL(列) 指这个表中的指定列不能筛选,其它列可以。
Values并没有取消表或列的筛选的功能。

我们尝试使用Values操作一下:
【度量值】总销售2 = sum(Sheet2[销售])
【度量值】排名3 = RANKX(Values(Sheet2),[总销售2])
【度量值】排名4 = RANKX(Values(Sheet2[商品]),[总销售2])

明显都是错的!
这个原理我们通过ALL函数来讲,你就明白为什么不能使用Values函数了:
现在我们换成ALL函数
【度量值】总销售2 = sum(Sheet2[销售])
【度量值】排名3 = RANKX(all(Sheet2),[总销售2])
【度量值】排名4 = RANKX(all(Sheet2[商品]),[总销售2])

很明显,【排名3】是错误的,那为什么呢?
我们看看【排名3】和【排名4】的工作原理:
【度量值】排名3 = RANKX(all(Sheet2),[总销售2])

【脑子里想像的场景】当我们在矩阵上使用行标题为商品时,相当于是分组聚合,我们的销售是可以按商品聚合的,但是排名不行,以A商品为例,第1名和第4名,请问加在一起是多少名?这就是不能使用ALL(表)的原因,因为我表中的商品有重复!
RankX并不是由矩阵筛选的,而是由第1参数生成的那张表迭代每一行产生的排名。
说人话:就是相当于Vlookup把ABC的排名V过来,所以我们要限制商品列不能筛选RankX生成的度量值,因为Values函数生成的表本身无法限制筛选,故不能使用Values函数。

如上图所示:A和B商品显示1并不是第1名的意思,而是排名不能在这里重复计算,C商品排名就是3所以就显示3,但是A和B商品的排名无法体现,故显示为1,同使用Values函数一样的道理。
Ps: 如果我们想看每条记录的排名,这么写是没错的。原理我们已经通过【排名3】生成的示意图展示了。

【度量值】排名4 = RANKX(all(Sheet2[商品]),[总销售2])

矩阵的行标题,只是将RankX产生的排名体现出来,这个排名在第一参数表中就已经生成了。

同理,度量值排名4也不能对每条记录进行排名,如下图:

因为【排名4】只限制了商品列不能筛选,序号列是可以筛选,所以仍然出错,全部显示为1。
其实,RankX应该怎么写,并没有标准答案,而是你想做什么,由你的业务需求决定的。
RankX的知识还有很多,未来几节课我们会一直讲这个函数和关于RankX的答网友问。请大家耐心等待。

《孙兴华讲PowerBI火力全开》PowerBI必学课程
https://www.bilibili.com/video/BV1qa4y1H7wp
《DAX神功》文字版合集:
https://www.bilibili.com/read/readlist/rl442274
《DAX神功》视频版合集:
https://www.bilibili.com/video/BV1YE411E7p3
PowerBI(DAX函数)、PowerQuery(M函数)、Python办公自动化、Python爬虫、Python数据分析、ExcelVBA、WordVBA、AccessVBA、MySQL等等
https://www.bilibili.com/read/cv10222110