在DAX函数中,关于排名的函数有RANKX和TOPN函数,这两个函数白茶已经写过很多文章了,都是关于排名问题的,但是,实际情况中,根据我们中国式报表的需求,怎么可能仅仅如此?
先看数据:
需求对话:
BOSS:白茶,我需要一个排名!
我:我之前不是做过很多期了么?
BOSS:不行!你做的什么玩意,怎么排第一的那么多人?我要排出个123来,不要并列!懂不懂!
我:...(@#¥……@%¥!)那,并列的情况下靠什么判断么?
BOSS:你咋这么笨呢!时间!先到先得!
我:↓↓↓↓↓
将数据导入到PowerBI中,结果如下:
编写基础代码:
代码语言:txt复制金额 =
SUM ( '示例'[销售金额] )
结果如下:
按照我们常规的写法,代码是这样子的:
代码语言:txt复制排名 =
IF ( HASONEFILTER ( '示例'[员工] ), RANKX ( ALL ( '示例' ), [金额],, DESC, DENSE ) )
结果是这样子的:
按照咱们中国老板的需求,1就是1,2就是2,我不要那么多花里胡哨的,1就是1!也是很无奈的。
群里面的大佬有很多种解决方案,主要都是采用构建虚拟表的方式,白茶觉得不太好理解。
但是有一个别的思路,就是绕开虚拟表,在不使用任何其他维度的情况下该如何处理呢?
刚才说了,当金额一致的情况下,需要考虑时间,那么把时间也作为数值加进去不就得了!这个属于利用加权的算法,将时间与金额合二为一。代码如下:
代码语言:txt复制并列排名 =
IF (
HASONEFILTER ( '示例'[员工] ),
RANKX (
ALL ( '示例' ),
[金额] DIVIDE ( 10000, CALCULATE ( MIN ( '示例'[日期] ) ) ),
,
DESC,
DENSE
)
)
结果如下:
这样是不是就达到了中国式报表的需求了?解释一下:
IF HASONEFILTER是为了去掉总计栏显示的问题,之前提到过很多次了。
ALL的使用是绝对排名,为整张表中的排名准备。
DESC是按照从大到小排名,DENSE是按照中国式排名进行。
核心,在于添加了一个DIVIDE的值。当日期越大时,这个值越小,所有的金额都与这个值相加作比较,就相当于给每一个金额加了小数位,而小数位的值由日期决定。
特别注意,MIN函数外面需要嵌套一层CALCULATE函数,因为涉及到行上下文日期转换为筛选上下文日期的问题。
小伙伴们,GET了么?
(白茶:Biu~❤)