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

Power BI之DAX神功:第3卷第20回 无参数的ALLSELECTED函数,用1+1等于2的方法避坑

2021-12-15 09:16 作者:孙兴华zz  | 我要投稿

ALLSELECTED 函数支持三种类型的参数:

单列或多列:ALLSELECTED (表名[列名])

整张表:ALLSELECTED (表名)

关于以上两种参数,我们分别在《DAX神功》第1卷第11回、第3卷第18回、第19回做了详解

当然,我讲的并不深入,因为路不只一条,有些困难是要迎面而上,但是有一些是可以避开的。我自己也选择避开!当然我并不反对你深入研究,上节课我也告知你深入研究的地方。

你还可以使用不带参数的 ALLSELECTED(),今天我们重点讲讲不带参数的情况

注意:在不使用任何参数的情况下ALLSELECTED函数只能作为 CALCULATE或CALCULATETABLE 调节器。因为没参数,它肯定无法返回成一张表,自然也就做不成表函数。

有了上面这句话,问题就简单多了,之所以单拿出来讲,是因为DAX专家很多代码没有必要写成那样,在学习ALLSELECTED()无参数之前,我们需要先理解ALL()无参数。


一、ALL()无参数

【度量值】总分 = SUM('成绩表'[分数])

【度量值】all学生表 = CALCULATE([总分],ALL('学生表')) // 删除学生表所有列的筛选

【度量值】all学生表姓名 = CALCULATE([总分],ALL('学生表'[姓名]))

// 只删除学生表姓名列的筛选

【度量值】all学生表班级 = CALCULATE([总分],ALL('学生表'[班级]))

// 只删除学生表班级列的筛选,但是学生表姓名列可以筛选

【度量值】all成绩表学号列 = CALCULATE([总分],ALL('成绩表'[学号]))

// 删除成绩表学号列的筛选,不影响其它筛选

【度量值】all成绩表 = CALCULATE([总分],ALL('成绩表'))

// 因为学生表与成绩表是一对多关系,成绩表是多端向一端扩展学生表中的所有列,所以当all成绩表时,成绩表的扩展表中所有列都删除筛选。

【度量值】all无参数 = CALCULATE([总分],ALL())

// 在整个模型中删除任何筛选器

因为我们只有两张表,all()返回的结果与all(成绩表)是一样的

为了解释这个问题,我们再手贱一次

《DAX神功》第1卷第2回我们学习了,箭头方向符合条件时,在整条线路中不存在多对多关系时,开始表可以筛选结束表。我们制度两个度量值:

返回结果:

原本学生表中的姓名列是可以筛选日期表,但是当使用all()整个模型中原本能用的筛选器都被删除了。因为学生表和日期表都是一端表,你总不能说在一对多关系中一端表有扩展列吧?

二、ALLSELECTED()无参数

ALLSELECTED():激活任何列最后一个影子筛选器,如果没有影子筛选器当然无法激活了。

通过商品编码,建立一对多关系:

我们将上面两个度量值放入矩阵:

《DAX神功》第3卷第18回 原例,只是改了个表。我跟大家说矩阵就是查询,是查询就能生成表,就可以通过新建表举例:过程就不再重复了,我们直接新建表

返回结果:

显式筛选器:苹果、土豆、西瓜

影子筛选器:商品表[商品名称]通过显式筛选器后显示的可见行

allselected删除所有筛选器,激活影子筛选器后进行计算,所以每一行显示6+4+null=10

现在我们将其改成allselected()无参数

返回结果:

因为我们案例中,只有一个列上有影子筛选器,且只有一个影子筛选器。我跟大家一直说,不建议你们嵌套或在复杂公式中使用allselected函数。切记!如果我们尽量避开allselected函数,换而言之,ALLSELECTED()存在的意义就很小了。

三、计算从未购买过某些产品的客户数量

这是一道由DAX专家举出的例子,如果是我,我会用下面的方法做:

返回结果:

上面的方法,就算是DAX初学者也会吧?这不就避开了Allselected了吗?

allselected一旦使用,连专家也会进入走火入魔的状态,当年欧阳峰前辈第2次华山论剑,虽然胜出,可是身体状况...例如这个案例,DAX专家这样写。(如果你觉得书上不是这样写的,麻烦您问问作者或译者,看是不是有勘误)

度量值如下:

返回结果:

你看上去没毛病吧?你筛选一下商品名称看看

解决方法,将allselected()改成all()

返回结果:

因为filter创建了tb1中所有列的影子上下文,如果使用allselected()他会激活这个影子筛选器,可是我现在的实际情况就不能让它筛选。如果一定要这么写公式,我也是这样写:

返回结果:

这不也避开了allselected吗?当然这样写都没必要,你就用我第一种方法就好了。

四、将销售额计算范围缩小至首年客户

意思:B1和B2第1年就买东西了,要计算首年顾客,在每个年份的消费金额。不需要B3的数据。

制作动态日期表:

我们先看看DAX专家是这样写的:写的对!太对了!

返回结果:

你知道困扰你的地方在哪里吗?因为他使用了ALLSELECTED(),哪有影子呀?

在这里使用ALLSELECTED()和all()是一样,没影子就跟all()一样了

而且tb2根本就不用all(),干嘛呀?先删除筛选再恢复筛选。你看我下面的写法:

返回结果:

公式分析:

(1)FIRSTNONBLANK('日期表'[年],[总销售])  // 第一个销售不为空的年份 ,返回2020

// 这个2020具有'日期表'[年]的数据沿袭,详见《DAX神功》答网友问12

(2)这个2020可是固定的,不能筛选,因为我们确定的是首年永远都是2020年。

CALCULATETABLE(FIRSTNONBLANK('日期表'[年],[总销售]),ALL())

(3)CALCULATETABLE(VALUES('销售表'[会员卡号]),tb1) // 筛选2020年的会员卡号,返回会员卡号是B1、B2的这张表

(4) CALCULATE([总销售],tb2)  // 筛选会员卡号是B1和B2的销售

我就问你,这里面有原理吗?这不都是语法吗?

好比,快递就在楼下快递柜里,我下去拿回来就好了!不行,为了研究原理,我一定要去法院起诉,让法院把这个快递判给我,我才能去取。结果是相同的,最终快递都回到我手中了,可是后者有什么必要呢?这快递本来就是我的。

再次建议大家,allselected我们只用最基本的功能,其它功能我遇到的基本可以被替代,不要给自己增加麻烦。

《孙兴华讲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神功:第3卷第20回 无参数的ALLSELECTED函数,用1+1等于2的方法避坑的评论 (共 条)

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