如今市面上教程很多,但即使是经典著作《DAX圣经》,也是建议读者研读计值上下文和Calculate这两个章节,最好几遍以上。这篇文章希望可以增进道友的理解。
毋庸置疑DAX是POWER BI的大脑,而计值上下文可以说是DAX的基石。
计值上下文有两类:
1、行上下文:当前行的环境;
大多数教程和文章就类似这一句,实在让人难以捉摸到底是什么东西,一边PBI是列式数据库,不存在行的概念,那么这行的环境是怎么来的呢?即使看完DAX圣经的优化主题的章节,我也没明白对数据进行三种方法的压缩后,详细如何创建行的环境,姑且认为DAX引擎就是能够创建一个类似有行标的数据表吧(用来识别行与行间的不同);
行上下文创建的方式有两种:1、在数据模型内的表新建计算列时自动创建;2、迭代器函数创建;
行上下文的作用是直接取到该行中某列的值,因而在行上下文的环境可以只放某个列名,不需要(但可以)外套一个函数。
2、筛选上下文:计量的环境;
筛选上下文存在于数据透视表的行列、切片器、公式内部的筛选器参数;
筛选上下文的作用是引用某个列进行聚合计算,因此在筛选上下文的环境一定要有聚合函数;
聚合计算因不同的筛选上下文而得到不同的值,这也就是数据透视表用同个公式,却在不同的数据透视表的单元格得到不同的值。
拿个简单的表作例子:
一个只有两列的表,表名Table:
增加如下4个计算列:
OnColumn = 'Table'[Value]
WithSum = SUM('Table'[Value])
WithSUMX = SUMX('Table','Table'[Value])
WithCalculate = CALCULATE(SUM('Table'[Value]))
OnColumn:因为模型内的数据表自动创建了行上下文,确定计算列各个计算结果的行环境(类似行标);再指定[Value]列,便可以“一行一列”确定一个值;
WithSum:SUM函数是SUMX的简化版,在某些情形中必需按SUMX的原理进行理解,如累计合计的计算。因此,跳到下一个进行理解;
WithSUMX:(拿图的第1行结果6说事儿)由于模型内的数据表只有行上下文,没有筛选上下文,迭代器函数忽略行上下文,因此SUMX的第一个参数返回表Table的所有行,而非只有一行;SUMX迭代第一个参数的每一行(创建行上下文)并进行计值(同OnColumn的原理),最后聚合计值结果;
WithCalculate :(拿图的第1行结果2说事儿)此处发生上下文转换,Calculate将模型内的数据表自动创建的行上下文转换为筛选上下文。此时,内部的SUM,用SUMX理解而言,第一参数会受到筛选上下文的影响,经筛选后得到2行(第1、2行)数据,因此结果为1+1=2;
思考下面计算列的计值流:
WithCalculate2 = CALCULATE(SUMX('Table',SUM('Table'[Value])))
总结
上下文的掌握是DAX的基础,迭代器函数和Calculate函数的了解,更有助于计值流基础的掌握。