4.2 最重要的DAX函数 - Calculate

本节简介

Calculate可以说是DAX中最重要的函数,是实现所有复杂运算的基础。

它的运算逻辑其实相当复杂,在本文中,可能会有很多概念在初读到时候不太理解,或是意识不到相关的作用,这时不用着急,先对相关内容有一点印象即可,随着使用的增加,对它的理解也会加深,也可以随时返回来重新阅读和理解。而且我们的示例中,也会先演示最常用的用法,对于只需要制作简单报表的同学,并不需要理解太深。

Calculate的作用

Calculate函数是DAX语言中最为特殊的函数,因为只有它是可以修改筛选上下文的。(ps:还有calculatetable,与calculate类似,但返回值是一个表,calculate的使用更高频)

我们知道,上下文是度量值运算的外部环境,改变了上下文,就改变了最终的运算结果,因此使用calculate搭配各类基础函数,就可以实现多种统计运算。

该函数支持多个参数的输入,其写法如下:

度量值 = calculate(表达式 , 筛选器1 , 筛选器2 , … ,筛选器n)

其中第一参数“表达式”是必填的参数,是我们要计算的逻辑,这里可以是一个聚合运算 度量值,后面的各个筛选器就是给定一个或一组筛选条件。

在进行运算时,calculate会先复制全部的外部筛选器(例如切片器、筛选器、视觉对象上的轴、矩阵中的行列、其它视觉对象上传递来的筛选条件等),然后逐个与函数中给出的筛选器做比较,若在某个列上没有重复的筛选器则保留,若有重复,则使用calculate函数中给出的条件替换外部筛选器。

之所以强调是聚合运算,就是因为初开始接触PowerBI时,许多同学容易误入之前在excel中的习惯,忘记在PowerBI中所有的数据都是按列存储的,任何一个表达式的底层都可能是若干行数据,而度量值在输出时都是一个点,因此必须要指定聚合的规则,否则会报错,大部分情况下都应该是求和sum。

下面我们通过一个简单的例子来加深一下对它工作原理的理解。

Calculate工作原理

之前我们已经搭建好了一个简易的分析模型(详见 Power Pivot中数据建模 ),模型中有国家表、年份表两个维度表,另有人口总数、占比数据两张数据表,均是通过国家编码、年份字段与维度表建立的连接。

如下图所示,我们在之前的课程中曾写过一个最简单的度量值:

sum人口数 = sum('人口总数'[总人口])

现在将它放在一个矩阵(相当于一个透视表)中,矩阵的行里是地区和国家名称,这两个字段均来自国家表,可以看到字段窗格中对应字段上有对勾标记,同时还在此视觉对象的筛选器(见筛选器窗格)中设置了一个筛选是地区不等于空白;

矩阵的列中我们放的字段是年份表中的年份,同时也在视觉对象的筛选器上对该字段加了一个大于等于2020的条件。

因此我们可以看到,矩阵中显示了2020和2021两年各地区的人口总数,且点击加号可以向下钻取到国家。

接下来,我们新建一个度量值如下,并把它也加入矩阵中:

2021南亚人口数 = CALCULATE([sum人口数],'国家表'[地区]="南亚",'年份表'[年份]=2021)

首先来解释一下这个度量值的含义,第一参数是之前创建的度量值[sum人口数],即使用它所定义的对人口总数列求和的运算逻辑,同时又添加了两个筛选条件,即国家表的地区为南亚,年份表的年份为2021。

啰嗦几句题外话,由于我们之前已经在模型中创建了连接关系,可以使用维度表来完成对数据表的筛选,所以在度量值中填写的这几个筛选虽然是跨表的,但仍会沿着模型中规定的关系流向,对目标表完成筛选。在搭建报表时,我们都推荐都使用维度表中这些通用的字段来进行筛选和度量值书写,这样一方面不易出错,再一方面在同时调用多表数据时才能形成正确的上下文。

首先看红框内的部分,[2021年南亚人口数]这个度量值在所有的地区的统计结果都是一样的,这是因为虽然来自行的筛选器分别传递了不同的地区,但calculate函数中对同一列(国家表的地区列)也做了新的筛选,此时使用内部筛选替代外部筛选,因此在所有的行统计出的全是南亚的值。

然后再看蓝色部分,即南亚这一行的统计,由 [sum人口数] 可以看出,该地区在两年间的人口是不相等的,但[2021年南亚人口数] 得到的却都是相等的,等于2021年的统计值。同样的道理,虽然列上提供了不同的年份筛选,但由于在该年份列上还有calcuate提供的筛选,于是用函数内的替换外部的,因此将时间条件变更为了2021,这样就无视外部筛选完成了指定年份的计算。

此时我们若将行标题展开,可以看到,神奇的事情出现了,[2021年南亚人口数] 在下钻到国家时,只有2021年这个时间条件生效了,在不同国家中计算得到的还是当前国家的人口,然而如果到了别的地区,在国家上则根本没有数值了。

这是为什么呢?其实仔细回想一下calculate的计算逻辑,就能反应过来了。

对于南亚的任意一个国家,譬如印度,在计算时,外部筛选是:

'国家表'[地区]="南亚" 和 '国家表'[国家]="印度"

而calculate提供的筛选条件是 '国家表'[地区]="南亚"

只在地区列上出现了重复,使用内部筛选替换外部,所以还是 '国家表'[地区]="南亚";到了国家列,只有来自外部的筛选、calculate并未提供新的筛选条件,因此保留在该列上的筛选。

于是最终计算的上下文是:'国家表'[地区]="南亚" 和 '国家表'[国家]="印度"

于是各国统计得到的还是正常的结果。

那么再看一下其它地区的国家,譬如尼日利亚,它的外部筛选是:'国家表'[地区]="撒哈拉以南非洲地区(不包括高收入)" 和 '国家表'[国家]="尼日利亚"

在地区列上因为筛选器重复了,用内部替换外部,得到 '国家表'[地区]="南亚" ,在国家上没有冲突,因此保留原来的筛选,于是最终的上下文是:

'国家表'[地区]="南亚" 和 '国家表'[国家]="尼日利亚",而按这个筛选条件在国家表中是找不到记录的,所以在数据表中筛选不出有效的值,于是计算结果为空。

Calculate能接受的3类筛选

calculate函数中可以接受的筛选条件有三种:

布尔表达式

在前面的例子中,我们所书写的如 '国家表'[地区]="南亚",对calcuate来说其实就是布尔表达式,相当于遍历国家表的地区列,逐行判断是否等于南亚,并返回一组True/False值,calculate统计时只对为True的行做运算。

我们也可以传入一个表来作为筛选条件,相当于使用这个表依托于关系模型来对数据进行筛选,通常会通过filter函数实现。

调节器

DAX语言中还有一些特殊的函数,如 ALL、ALLSELECTED、KEEPFILTERS、USERELATIONSHIP 等,它们的作用是变更上下文的生成,进而影响统计结果。

布尔表达式的方式是最容易明白的,其余两类筛选可以在未来学习相关函数时再加深理解。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值