CALCULATE是DAX最重要的函数,它的功能就是DAX的内在逻辑,它是实现DAX数据分析功能的引擎
语法
CALCULATE(表达式,筛选器1,筛选器2…)
参数1:表达式,可以是各种聚合函数
参数2(可选):是一系列筛选条件
如果多个筛选条件,用逗号分隔,所有筛选条件的交集形成最终的筛选数据集合
根据筛选出的数据集合,执行参数1的聚合运算并返回运算结果
案例
通过案例来理解CALCULATE函数,同时加深理解度量值和上下文
1、POWER BI 导入产品明细表

2、新建度量值,计算每款产品的数量
产品数量 = COUNTROWS('产品明细表')
'产品明细表'中,每个产品就是一行,所以通过计算表格的行数就是所有产品的数量结果
3、外部上下文:表格的行列标签
在‘报表’看板,插入‘矩阵’,选择‘产品名称’和‘产品数量’,显示每款产品数量为1(可以试试把‘产品名称’改成‘品牌名称’、‘产品类别’等)
这里矩阵表的行标签(产品名称)就是该度量值的外部上下文,通过外部上下文对产品数量进行区隔、筛选

4、筛选条件为空,不影响外部上下文
新建度量值
产品数量无筛选 = CALCULATE('产品明细表'[产品数量])
①公式里只有第一个参数,直接引用了之前的度量值,DAX度量值之间是可以引用的,该公式也可以改成完整模式(这点跟Excel非常类似):
产品数量无筛选 = CALCULATE( COUNTROWS('产品明细表'))
②筛选条件为空,将该度量值拉到矩阵表,因为DAX语言内部没有筛选(即没有内部上下文),所以筛选结果依然为外部上下文

5、添加筛选条件,缩小上下文
5.1、单条件: 新建度量值
产品数量华为 = CALCULATE('产品明细表'[产品数量],'产品明细表'[品牌名称]="华为")
这里通过1个筛选条件,筛选出品牌为‘华为’的产品,所以只显示‘华为’的所有产品(平板,手机,智能手表)

5.2、多条件: 新建度量值
产品数量华为的手机 = CALCULATE('产品明细表'[产品数量],'产品明细表'[品牌名称]="华为",'产品明细表'[产品类别]="手机")
这里通过两个筛选条件,筛选出品牌为‘华为’的‘手机’类型的产品,所以只显示‘华为手机’

5.3、FILTER条件筛选
多条件也可以和FILTER函数结合(这里作简单了解,后面会详细介绍FILTER的用法),新建度量值:
多条件FLITER与 = CALCULATE('产品明细表'[产品数量],FILTER('产品明细表','产品明细表'[品牌名称]="华为"&&'产品明细表'[产品类别]="手机"))
多条件FLITER或 = CALCULATE('产品明细表'[产品数量],FILTER('产品明细表','产品明细表'[品牌名称]="华为"||'产品明细表'[产品类别]="手机"))
(DAX函数,多条件‘与’用‘&&’;多条件‘或’用‘||')

6、结合ALL函数,清除上下文
新建度量值
产品数量ALL = CALCULATE('产品明细表'[产品数量],ALL('产品明细表'))
ALL('产品明细表')的意思是清除了‘产品明细表’里的所有筛选,
——内部上下文-DAX已经清除了所有筛选,外部上下文-矩阵表行标签不起作用了,所以每行的数值都是统计的该表的所有产品数量15

计算占比
利用ALL清除筛选,我们就能计算产品占比了,新建度量值
产品占比 = '产品明细表'[产品数量]/'产品明细表'[产品数量ALL]

7、重置上下文
新建度量值
产品数量-重置华为 = CALCULATE('产品明细表'[产品数量],ALL('产品明细表'),'产品明细表'[品牌名称]="华为")
为了加深理解,这里跟另外一个度量值对比理解:
产品数量华为 = CALCULATE('产品明细表'[产品数量],'产品明细表'[品牌名称]="华为")

先用ALL函数清除外部上下文:矩阵表行标签,此时矩阵表的行标签已经失效了;然后再增加一个筛选条件:从全部产品中统计品牌名是华为的产品,因为矩阵表的行标签已经失效,所以每行的数量为3
如果没有提前用ALL函数清除外部上下文,筛选出来的3种华为产品会根据矩阵表的行标签二次筛选,数字分别为1
总结
CALCULATE的计算逻辑,通过单个或多个筛选条件,筛选出一个数据集合,然后根据第一个参数执行聚合运算,这就是DAX要实现的功能:提取有用数据并执行聚合运算。
文章后留言,获取练习文件