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索引] ) )
    )
)

添加一个切片器,结果如图:

image

这样就可以随着切片器的变动,随意调整我们想要的TOPN了。

传送门丨:

PowerBI中的排名问题丨RANKX函数(修订)

迭代循环丨SUMX函数(修订)


小伙伴们❤GET了么?

白茶会不定期的分享一些函数卡片

(文件在知识星球[PowerBI丨需求圈])

这里是白茶,一个PowerBI的初学者。

下面这个知识星球是针对有实际需求的小伙伴,有需要的请加入下面的知识星球。

请在PC端查看,有部分图片无法在移动端显示。
PowerBI丨白茶