白茶认为,这个东西可以不用,但是该了解需要了解。感谢@群里面各位大佬的指点,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的初学者。