RANKX函数丨最终话

2021-09-01 14:39:15 浏览数 (1)

白茶认为,这个东西可以不用,但是该了解需要了解。感谢@群里面各位大佬的指点,RANKX函数的最后一点也彻底明白了。

先来看看RANKX函数的微软语法:

代码语言:txt复制
DAX=
RANKX(<table>, <expression>[, <value>[, <order>[, <ties>]]])

一共五个参数,前两个是必须的,后三个是可选参数。

第一参 表:可以是直接的表,也可以是用函数生成的表。

第二参 表达式:聚合表达式,或者写好的度量值。

第三参 值:可选。可以是个聚合表达式,也可以是一个直接的数值。

第四参 排序:可以是0或1,也可以是ASC或DESC,升降序使用。

第五参 排序方法:Skip国际排序;Dense中国式排序。

这是微软官方的介绍,咱们来看具体的例子。

这是白茶准备的基础数据,一份消费记录。

这是白茶为了测试第三参数准备的一份数据,下面就开始测试。

编写基本的RANKX代码:

消费额代码:

代码语言:txt复制
消费额 =
SUM ('示例'[消费] )

基本排名代码:

代码语言:txt复制
排名 =
RANKX ( ALL ('示例'[客户ID],'示例'[类型] ), [消费额] )

结果如下:

代码呈现出来的结果,我们不难发现其实有两个地方是不合理的,一个是下面的几个客户实际上并没有消费,一个是总计栏显示问题,优化一下我们的代码:

一、去掉总计栏不合理使用IF HASONEVALUE:

代码语言:txt复制
排名优化第1次 =
IF( HASONEVALUE ('示例'[客户ID] ), RANKX ( ALL ('示例'[客户ID],'示例'[类型] ), [消费额] ) )

结果如下:

这种用法可以说是RANKX函数最常用的套路之一,多维度排名。

稍后,白茶会说怎么处理没有消费额的排名,咱们先来看看别的。

我现在想知道'客户表'中,具体客户的排名,咋弄?

将客户名称这一项放在表格中进行对比,会发现之前的排名也已经失效了,这是因为客户与消费额排名分属于两个表,而我们之前使用的度量值代码并没有涵盖这个表,咋整?优化我们的代码:

二、笛卡尔积俩表排名用GENERATE,俩表及以上用CROSSJOIN

代码语言:txt复制
排名优化第2次 =

IF(

       HASONEVALUE ('示例'[客户ID] ),

           RANKX ( GENERATE ( ALL ('客户表'), ALL ('示例') ), [消费额] )

)

结果如下:

代码语言:txt复制
排名优化第3次 =

IF(

HASONEVALUE ('示例'[客户ID] ),

RANKX ( CROSSJOIN ( ALL ('客户表'), ALL ('示例') ), [消费额] )

)

结果如图:

可以看得出来,两个DAX代码的结果是一模一样的。当表数量为2时,使用哪个都可以。

三、去掉没有数据的排名AND FILTER

有时候难免遇到这种情况,就是我有两个表,一个是事实表,一个是维度表,但是有一部分维度是没有数据的,DAX会将空值自动填充排名,那该怎么整呢?(感谢@冬神)冬神的思路是,双重判断,直接清空没有数据的情况。编写如下代码:

代码语言:txt复制
排名优化第4次 =

IF(

AND( HASONEVALUE ('示例'[客户ID] ), [消费额] >0),    

RANKX (FILTER ( CROSSJOIN ( ALL ('示例'), ALL ('客户表') ), [消费额] >0),       

 [消费额],    

    ,      

  ASC 

   )

)

结果如下:

对比图:

这里白茶将第三个代码加入了排序,是为了对比作用。后面会细说。

这里解释一下含义。

第一段的AND HASONEVALUE 值,实际上是双重判断,判断是否有客户信息,是否有销售,如果符合情况,执行正确结果,否则输出为空。

第二段的FILTER是为了筛选出笛卡尔积两个表中所有消费数据不为空的数据。

第三段才是进行排名,这里加入了ASC,是为了让小伙伴们更清楚的看到区别在哪。

没有加入双重判断,笛卡尔积有一百多种空值组合,当从小到大排序时,空值占了一百多个名额。

四、第三参的作用

RANKX函数一共有五个参数,那第三参的作用是什么呢?经常看到有的文章说第三参没啥用,或者用的不多。白茶在这里想说,都是看需求的,微软怎么可能会整一个没用的东西出来?(感谢@冬神@嘿神@韭菜

实际上,如果第三参我们不输入的情况下,第二参也是第三参,一旦输入第三参,结果展示的是第三参按照第二参排名的位置。

这么说可能有点迷糊,举个例子吧。假如我有一份普通班级学生成绩的分数,和一份尖子班成绩排名,我想看看我的学生在尖子班能排第几,这不就是实际第三参的用途么?编写代码如下:

代码语言:txt复制
第三参排名 =

IF(

AND( HASONEVALUE ('第三参'[第三参] ), [消费额] >0),    

RANKX (FILTER ( CROSSJOIN ( ALL ('示例'), ALL ('客户表') ), [消费额] >0),       

 [消费额],

MINX ('第三参','第三参'[第三参] )    

)

)

结果如图:

右边的表格能很清楚的体现无关的数据,在之前排名大致所处的位置。

因为两个表之间并没有直接的联系,第三参需要我们自己筛选出相应的数据,否则排名就是错误的。

这里使用MINX进行迭代循环选择具体的数据。

五、第四参、第五参的作用

第四参主要的作用是按照从小到大排序,还是按照从大到小排序,上面的双重判断已经使用了一次,这里就不过多赘述了。有两个选项如下:

ASC表示从小往大排序;DESC表示从大往小排序。

第五参的作用白茶说了,就是按照中国式排名还是国际排名。

比如说,我有一组数据,1、2、2、3、4。

国际排名就是1、2、3、3、5。

而中国式排名就是1、2、3、3、 4。

也是有两个选项:

Skip表示国际排名,而Dense是中国式排名。

这里白茶用的ALL函数,也是绝对排名的用法,如果是相对排名,各位小伙伴可以自行替换成ALLSELECTED。

这里说点别的。记得白茶有一期说过帕累托图么?当时有一个数据是按照日期维度累加,但是最后做表的时候无法按照帕累托的思路进行。

学到这里,其实这个问题可以用今天的排名来解决,代码如下:

代码语言:txt复制
优化帕累托累计求和 =

VAR HQ = [排名优化第4次]

RETURN

CALCULATE ( [消费额], FILTER ( ALL ('示例'), [排名优化第4次] <= HQ ) )

结果如图:

是不是这次很符合我们心中的结果?

(再次感谢群里大佬们的指点,谢谢)

小伙伴们,GET了么?

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

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

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

0 人点赞