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

PowerBI之DAX神功:第1卷第21回 Calculate调节器USERELATIONSHIP函数

2021-08-26 20:05 作者:孙兴华zz  | 我要投稿


无忌哥哥永远不可能与黄衫女在一起,他们之间不会建立关系

但是,无忌哥哥与芷若妹妹和敏敏之间有着说不清的关系。

不过,当无忌哥哥跟芷若暧昧时,敏敏肯定不在;反之,与敏敏暧昧时,芷若也不在。

实线是:现任关系

虚线是:备胎关系

所以,无忌哥哥被称作渣男,他并没有违法;如果两条都是实线,那就违了49年以后的法了。

但是,无忌哥哥很聪明,他在虚虚实实中不停的变幻,这种事,就是放在今天,也只能封杀他,撤了他明教教主的职务,抓不了他。(前提他必须是知名人士,如果是江湖中人,也只能道德谴责他)

无忌哥哥是通过什么方法,将虚线关系启用,同时实线关系自动变成虚线?

一、USERELATIONSHIP函数

张无忌是Calculate,USERELATIONSHIP函数是调节器,它不返回任何值,它的作用是开启指定关系并停之原来的关系。

这个函数《孙兴华讲PowerBI火力全开》笔记28.04中详细讲解过,而且还举了两个案例,我们今天不是来炫案例的,这是原理课,我们只讲原理:(案例请看《火力全开》)

需求1:我想使用一端表的日期筛选入职人数

入职人数1= count('多端表'[姓名]) 

入职人数2= countrows('多端表')

入职人数3=count('多端表'[入职])

以上3个度量值都可以实现入职人数的筛选(功能相同)

需求2:我想使用一端表的日期筛选离职人数

这时,您需要先切换两张表的连线关系

离职人数1= count('多端表'[姓名]) 

离职人数2= countrows('多端表')

离职人数3=count('多端表'[入职])

以上3个度量值都可以实现相同功能,但是你在做汇报时,你不能在表上改关系玩呀?

这时,我们可以建立一条实线关系,再建立一条虚线关系:

写两个度量值:

入职人数 = count('多端表'[姓名])

离职人数 = CALCULATE([入职人数],USERELATIONSHIP('一端表'[日期],'多端表'[离职]))

新建一张表:方法源于《DAX神功》第1卷第3回

参数表

VAR tb = 

    {

        ("入职"),

        ("离职")

    }

Return

    SelectColumns(tb , "项目" , [Value])

再写一个度量值:

切换 =

switch(TRUE(),

SELECTEDVALUE('参数表'[项目])="入职",[入职人数],

SELECTEDVALUE('参数表'[项目])="离职",[离职人数]

)


的确很方便,但是你要注意一些问题:

1】两表之间可以有多条线,但只能有一条实线。

【2】你要保证两表是一对多关系

【3】在使用USERELATIONSHIP函数前,必须保证虚线关系已经建立。

我们假设你没有建立虚线关系,就使用USERELATIONSHIP函数会出现下面的情况:

入职人数 = count('多端表'[姓名])

离职人数 = CALCULATE([入职人数],USERELATIONSHIP('一端表'[日期],'多端表'[离职]))

【4】USERELATIONSHIP函数里面两个参数没有顺序,先写谁都可以,总之一个是主键另一个是外键,下面两个度量值都是正确的

离职人数 = CALCULATE([入职人数],USERELATIONSHIP('一端表'[日期],'多端表'[离职]))

离职人数 = CALCULATE([入职人数],USERELATIONSHIP('多端表'[离职],'一端表'[日期]))

【5】Calculate嵌套使用时,只有最内层USERELATIONSHIP函数生效

度量值=

Calculate(

Calculate([总数量],USERELATIONSHIP(主键,外键)),

USERELATIONSHIP(主键,外键)

)

《DAX神功第1卷第18回》讲到DAX所有函数都是从内向外,USERELATIONSHIP函数在calculate中使用只生效第1次

我们举个通俗的例子:

度量值=

Calculate(

Calculate([孩子],USERELATIONSHIP(张无忌,赵敏)),

USERELATIONSHIP(张无忌,周芷若)

)

张无忌和赵敏的孩子,永远都是他们俩的,变不成张无忌和周芷若的孩子

我们应用到自己的案例上来:

总人数 = count('多端表'[姓名])

离职数

Calculate(

Calculate([总人数],USERELATIONSHIP('多端表'[离职],'一端表'[日期])),

USERELATIONSHIP('多端表'[入职],'一端表'[日期])

)

离职数2= Calculate([总人数],USERELATIONSHIP('多端表'[离职],'一端表'[日期])

你将度量值【离职数2】嵌套进来,也是一个道理,谁和谁的孩子,DNA是改不了的。

入职数2=Calculate([离职数2],USERELATIONSHIP('多端表'[入职],'一端表'[日期]))

入职数2仍然是离职数2

【6】有人问calculate中可以嵌套多少个USERELATIONSHIP函数?

只有最内层的生效,外面的又不生效,你嵌套他做什么?

【7】USERELATIONSHIP函数不支持新建列?谁说的?

【度量值】总人数=count('多端表'[姓名])

在一端表上新建列没有问题:

新建列 = Calculate([总人数],USERELATIONSHIP('多端表'[离职],'一端表'[日期]))


但是在多端表中新建列就不行了

新建列=Calculate([总人数],USERELATIONSHIP('多端表'[离职],'一端表'[日期]))

先写成度量值再放到新建列上,也不行

度量值 = Calculate([总人数],USERELATIONSHIP('多端表'[离职],'一端表'[日期]))

我们耐心的从头开始分析:

<1>  关系 :日期~入职

新建列建立在一端表中:一端表筛选多端表:

新建列建立在多端表中:

<2>  关系 :日期~离职

一端表:

多端表:

<3>  两条关系

这次我先看多端表上新建列:

多端表,启用虚线关系,禁用实现关系

注意:Calculate是先建立关系,再应用于筛选器。

因为Calculate是先执行调节器USERELATIONSHIP函数,后执行筛选器

原来实线关系是先存在的,现在你现改的关系,所以要先执行调节器USERELATIONSHIP('多端表'[离职],'一端表'[日期])

再应用到筛选器

你重新建立一对多关系后,一端表中的列就被Vlookup到多端表了。

虽然,在我的案例中,1端表只有日期列,但是你看不到的并不是不存在,你始终要记住

一对多关系,就是一端表中所有列Vlookup到多端表中了。

这个时候你就要指定可以筛选的列,禁用Vlookup过来的那些列

列 = Calculate([总人数],USERELATIONSHIP('多端表'[离职],'一端表'[日期]),ALLEXCEPT('多端表','多端表'[姓名],'多端表'[入职],'多端表'[离职]))  

 //只有指定的列可以筛选,其它列不能筛选

反之,我在一端表中新建列就没这个问题,因为一端筛选多端,不会从多端获取内容

二、名词名句解释

《The Definitive Guide to DAX》中提到的 USERELATIONSHIP函数在激活关系时,关系的定义发生在引用表时,而不是发生在调用Related或其它关系函数时。

这句话翻译成通俗的解释:关系函数只能用在创建行上下文的函数中(例如迭代函数)

calculate和calculatetable 创建是筛选上下文,不能直接使用关系函数

三、筛选器与调节器的顺序


度量值1 = CALCULATE([总分],'Sheet1'[班级]="一班",'Sheet1'[姓名]="二班")

等价

度量值1 = CALCULATE([总分],'Sheet1'[班级]="一班" && 'Sheet1'[姓名]="二班")

解释: 这么写是没有结果的

正确的写法:

度量值1 = CALCULATE([总分],'Sheet1'[班级] in {"一班","二班"})


这样看不出顺序来,我们换成or的关系就看出来了,筛选器是自左向右的先后顺序

度量值2 = CALCULATE([总分],'Sheet1'[班级]="二班" || 'Sheet1'[班级]="一班")

度量值3 = CALCULATE([总分],'Sheet1'[班级]="三班" || 'Sheet1'[班级]="二班")

解释:筛选器从左向右

例如度量值2,找到2班就不会再找1班了,返回2班的分数

例如度量值3,找不到3班,但是能找到2班的,返回2班的分数


但是不同列筛选时,这个顺序对结果是无所谓的,但是仍然从左向右,例如:

度量值4 = CALCULATE([总分],'Sheet1'[班级]="一班" && 'Sheet1'[性别]="男")


《DAX》神功中我们讲解了两个调节器ALL和Keepfilters


ALL即可以是调节器,又可以是表函数

例如:all出现在例如迭代函数第一参数为表的时候,它是表函数

Filter(all(表[列]),筛选条件)

但是,放到calculate筛选器中时ALL系列函数的作用是Calculate调节器。

调节器优先于筛选器

度量值5 = CALCULATE([总金额],ALL('多端表'[姓名]),VALUES('多端表'[姓名]))

度量值6 = CALCULATE([总金额],VALUES('多端表'[姓名]),ALL('多端表'[姓名]))

解释:度量值5和度量值6,结果相同

步骤1:ALL调节器

步骤2:Values筛选器


《DAX神功第1卷第17回》Values做筛选器,它即是表函数又是筛选器,当它放到Calculate筛选器中,它就是筛选器


keepfilters也是调节器,可它不是Calculate的调节器,它是筛选参数调节器,它的作用是:恢复参数的筛选。


网友提问:关于度量值5计值顺序是怎样的?

度量值5 = calculate([销售额], all(日期表), values(日期表[月份]), all(商品表), keepfilters(商品表[商品种类]="A")) 


顺序,从左向右,先Calculate调节器,再筛选器:

第1步:all(日期表)

第2步:all(商品表)

第3步:values(日期表[月份])

第4步:keepfilters(商品表[商品种类]="A")    //让不能实现筛选的筛选器恢复筛选功能


小常识:

Calculate调节器有哪些?

Userlationship、Crossfilter、ALL、Allselected、Allexcept、Allcrossfiltered、Allnoblankrow

《孙兴华讲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







PowerBI之DAX神功:第1卷第21回 Calculate调节器USERELATIONSHIP函数的评论 (共 条)

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