欢迎光临散文网 会员登陆 & 注册

Power BI之DAX神功:第2卷第9回 多张表建立关系时RankX的应用

2021-09-26 14:09 作者:孙兴华zz  | 我要投稿

一、多表排名【度量值】

【度量值】总销售 = sum('表2'[销售])

【度量值】排名1 = rankx(ALLEXCEPT('表2','表2'[销售]),[总销售])

解释:如果只有【表2】这一张表,我们要得到排名可以写上面的公式也可以写成

【度量值】排名2 = rankx(ALL('表2'[编码]),[总销售])

但是,有多张表时(建立关系时),一端可以筛选多端,RankX就是要控制这些列不能实现筛选功能。所以,我们的写法是:除了【表2】中的“销售”列以外,都不能筛选。

Ps:如果您想释放某个列使其可以筛选,REMOVEFILTERS为您服务。详见《DAX神功》答网友问06

这是最简单、最好理解的一种方法,当然方法不止一种,还有一种方法是通过笛卡儿积的方式

但是在回答这个方法之前,我先回答一个网友的问题。

Ps:这种方法应用于度量值可以,应用于新建列时非常麻烦。本文章会详细讲解。

二、回答网友问题

问:网友看到某作者使用GENERATE函数,网友问:为什么我操作就失败了呢?可是我用人家作者提供的表操作正常呀?

【度量值】消费额 = SUM ( '示例'[消费] )

【度量值】排名1=RANKX ( GENERATE ( ALL ( '客户表' ), ALL ( '示例' ) ), [消费额] )

以上公式正常针对上表正常,但是换成自己的表就出错!

答:因为人家使用的是一对一关系,在《DAX神功》第1卷第1回,我就告诉大家,我遇到一对一关系会将其合并成一张表,再将类型和消费为空的记录过滤掉,就会减少很多原理知识。如下图所示:

你现在用这张表算排名,是不是就非常简单了?详细操作步骤雷同于《DAX神功答网友问06》这里就不再重复去讲了。

总结:表关系如果不是一对多关系,可以操作,但是你要多学原理知识。北京到天津做火车30分钟左右就到了,可你驾着筋斗云去了趟南天门,又跑了趟大雷音寺,最终到达目的地天津,不是不行是太绕了。如果你有10张表都是多对多关系,《The Definitive Guide to DAX》作者可能也会蒙。比如这个案例,我将其进行数据清洗,变成一张表,操作就简单了。一对一关系,不仅是用到了笛卡儿积,还要考虑示例表中缺失值的问题。

但是,当你照猫画虎,放到咱们这个一对多的案例上,【排名3】显示的结果并不是你需要的。

【度量值】排名3 = RANKX ( GENERATE ( ALL ( '表1' ), ALL ( '表2' ) ), [总销售] )

我先说一下你套用公式出错的原因:

GENERATE(表1,表2) :返回一个表,其中包含 表1 中的每一行与在 表1 的当前行的上下文中计算 表2 所得表之间的笛卡尔乘积 

GENERATE(all(表1),all(表2)) :返回一个表,其中包含 去重后的表1 中的每一行与在 去重后的表1 的当前行的上下文中计算 去重后的表2 所得表之间的笛卡尔乘积 

说人话:就是两张表做笛卡儿积(关于笛卡儿积的概念我就不再这里啰嗦了)

【1】友情提示

【新建表】 表 = GENERATE ( ALL ( '表1' ), ALL ( '表2' ) )

如果你两个表中有相同名称的列,新建表时会提示你,生成的新表不能有重复列。因为你是在生成实体表。如果你放在RankX第1参数中,它是虚拟存在,不会有这个问题。

防止有人一定要在新建表里测试,我们暂且将案例修改了字段名称:

【2】当表是一对一时的工作原理

【度量值】总销售=sum(表2[销售])

【度量值】排名 = RANKX ( GENERATE ( ALL ( '表1' ), ALL ( '表2' ) ), [总销售] )

这样可以正确的拿到每个人对应的排名。

【3】当表是一对多时的工作原理

【度量值】总销售=sum(表2[销售])

【度量值】1排名 = RANKX ( GENERATE ( ALL ( '表1' ), ALL ( '表2' ) ), [总销售] )

这样就拿不到正确的排名!

【4】正确的方法

【度量值】2排名 = RANKX ( GENERATE ( ALL ( '表1'[名称] ), ALL ( '表2'[编码2] ) ), [总销售] )

这样就可以拿到正确排名了:

当然,还可以使用另一个函数:

GENERATE函数可以应用两张表的笛卡儿积

CROSSJOIN函数可以应用多张表的笛卡儿积,例如:CROSSJOIN(表1,表2,表3……)

所以上面的案例我们换成CROSSJOIN也可以

【度量值】3排名 = RANKX ( CROSSJOIN ( ALL ( '表1'[名称] ), ALL ( '表2'[编码2] ) ), [总销售] )

三、多表排名【新建列】

我非常不建议你在新建列里做这样事,因为你考虑的东西要更多,比如,上节课讲的度量值要通过Calculate对计值的列取消筛选。例如:

【新建列】排名 = rankx(ALLEXCEPT('表2','表2'[销售]),CALCULATE([总销售],all('表2'[销售])))

这时又出现循环依赖,我们还要改!这个公式再改下去,你就晕了!

这时,我们可以用笛卡儿积(多表)的方式是最简单的:

【新建列】排名 = RANKX ( CROSSJOIN ( ALL ( '表1'[名称] ),ALL('表1'[编码]), ALL ( '表2'[编码] ) ), CALCULATE([总销售],ALL('表2'[销售]) ))

Ps:ALL('表2'[销售]) 这个事情我上节课说让你在新建列算排名时记住,否则7秒以后你就忘记了。

我们RankX部分的原理知识先暂时告一段落!下节课我们学习新知识!

《孙兴华讲PowerBI火力全开》PowerBI必学课程

https://www.bilibili.com/video/BV1qa4y1H7wp

《DAX神功》文字版合集:

https://www.bilibili.com/read/readlist/rl442274

《DAX神功》视频版合集:

https://www.bilibili.com/video/BV1YE411E7p3

PowerBI(DAX函数)、PowerQuery(M函数)、Python办公自动化、Python爬虫、Python数据分析、ExcelVBA、WordVBA、AccessVBA、MySQL等等

https://www.bilibili.com/read/cv10222110 


Power BI之DAX神功:第2卷第9回 多张表建立关系时RankX的应用的评论 (共 条)

分享到微博请遵守国家法律