RANKX函数延伸丨笛卡尔与TOPN问题(修订)
之前呢,白茶曾经分享过关于RANKX排名问题,但是在实际需求中,有时候我既想展示排名,但是同时我又想看看销售前几,该如何进行呢?这个问题就是标题——TOPN的问题。
上图,是白茶准备的示例文件,之前几期经常使用的一份销售情况。利用SUMX函数+RELATED函数进行汇总,求出销售金额,输入如下代码:
销售金额 =
SUMX ( '销售明细', '销售明细'[销售数量] * RELATED ( '产品表'[销售价] ) )
结果如图:
金额汇总完毕,接下来我们继续编写排名代码如下:
绝对排名 =
IF ( HASONEVALUE ( '产品表'[商品名称] ), RANKX ( ALL ( '产品表' ), [销售金额] ) )
结果如下:
这时候我们发现了,好像排名这里,似乎有点不对劲啊?根本就是错的啊!之前在RANKX那一期结尾的时候,白茶曾经说过,可以多维度排名,但是当时的前提是同一个表,可以使用ALL(‘表’[维度1],‘表’[维度2]…)这种模式,但是这种不是一个表的维度该如何处理呢?别着急,跟着我的思路走。
这里就延伸出一个概念了,两个表,我要两个表的条件列相互匹配,最后形成一个交集,这个概念是不是听起来很耳熟?没错,就是我们了解的笛卡尔积!
在PowerBI中,有DAX函数可以达到这种效果。
一、GENERATE函数
GENERATE函数语法如下:
DAX=
GENERATE ('表A','表B')
结果返回两个表的叉积。它的参数只能是两个表。
二、CROSSJOIN函数
CROSSJOIN函数语法如下:
DAX=
CROSSJOIN ('表A','表B'...)
结果是返回指定表的叉积。它可以有多个表参数。
当然,在这里只有两个表维度的情况下使用效果是一致的。
代码1:
优化绝对排名1 =
IF (
HASONEVALUE ( '产品表'[商品名称] ),
RANKX ( GENERATE ( ALL ( '产品表' ), ALL ( '分店表' ) ), [销售金额] )
)
代码2:
优化绝对排名2 =
IF (
HASONEVALUE ( '产品表'[商品名称] ),
RANKX ( CROSSJOIN ( ALL ( '产品表' ), ALL ( '分店表' ) ), [销售金额] )
)
将两个代码在数据中对比如下:
可以看得出来结果是一致的!这就说明两种方法在这里都是适用的。
排名问题解决了,那么该继续研究TOPN的问题了。
编写如下代码(这里用优化代码1举例):
销售前五 =
IF (
HASONEVALUE ( '分店表'[分店名] ),
CALCULATE ( [销售金额], FILTER ( VALUES ( '产品表' ), [优化绝对排名1] <= 5 ) )
)
结果如下:
结果展示没有任何问题。
那我要是想要灵活的变动成TOPN咋弄?
继续,添加参数:
修改上面的代码:
销售前N =
IF (
HASONEVALUE ( '分店表'[分店名] ),
CALCULATE (
[销售金额],
FILTER ( VALUES ( '产品表' ), [优化绝对排名1] <= SELECTEDVALUE ( 'TOPN索引'[TOPN索引] ) )
)
)
添加一个切片器,结果如图:
这样就可以随着切片器的变动,随意调整我们想要的TOPN了。
传送门丨:
小伙伴们❤GET了么?
白茶会不定期的分享一些函数卡片
(文件在知识星球[PowerBI丨需求圈])
这里是白茶,一个PowerBI的初学者。
下面这个知识星球是针对有实际需求的小伙伴,有需要的请加入下面的知识星球。
数据分析进阶之路,带你深入了解可视化技巧。