什么是上下文
上下文就是DAX公式计算时所处的环境
列如:=SUM(FactSales[SaleAmount])
这个公式解读为计算所有销售金额的总计
但是一般的透视表中常见的一种情况就是,产品按照类别和年份对比查看,比如白色的产品在2015年的销售总额。
公式不用变化,但是在将FactSales表中的[SaleAmount]列给到SUM进行计算前,已经进行了两次条件限定,一是颜色属性值为白色的产品,二是在2015年销售出去产品,两个条件以“和”运算,筛选出来的结果(2015年销售出去的白色产品)再给到SUM计算,这就是上下文,即公式实际进行计算的环境
上下文可以是行、列、切片器、筛选器,这些环境(计算上下文)进行“AND”运算筛选出来的结果再给到计算函数进行计算,这就有了只写一个公式,但是在透视表中可以计算出不同的结果。
存在两类上下文,在DAX中,这两类上下文始终存在并影响着公式的计算结果。一类筛选上下文,一类是行上下文
筛选上下文
如上面解释上下文中提到的,当建立一个透视表的时候,会对透视表的行、列进行设计,从而限定公式计算的环境,这些就是筛选上下文,所以开头用到的公式准确的解读应该如下:
=SUM(FactSales[SaleAmount])
计算筛选上下文中所有销售金额的总计
行上下文
先回忆一下EXCEL中的一个公式 :C1=A1+B1,然后,在C列填充这个公式,C列中每一有效行都得到一个不同的计算公式,比如 C20 = A20+B20。
EXCEL中我们可以定位某行和某列的交叉数据,使得我们可以操作公式对具体的单元格数值进行运算。
但是在PowerBI中的DAX可不是这样,我们能使用的最小颗粒度是列,而不是具体到某一个“单元格”,我们没办法也没必要操作“行”,在公式计算的时候默认使用了“当前行”这个计算环境。
把EXCEL中的公式用法挪到DAX中就成了这样:FactSales[GrossAmount] =FactSales[SaleAmount] + FactSales[DiscountAmount] ,这里的公式只用了列名,但是每个行都正确的计算出了结果,怎么做到的呢?为什么公式不会用第一行的[SaleAmount] 的值和第二行的[DiscountAmount]值进行计算?
我们给了两列值到公式中,当公式开始进行计算的时候,DAX内部是一行一行进行计算的(实际算法会有不同,但无需理会),第一次计算的时候,有一个隐含的计算环境:“第一行”。所以这个时候公式接收到的[SaleAmount]值只有一个,[DiscountAmount]值也只有一个,都是第一行的值,结果当然也只有一个(结果给到新列FactSales[GrossAmount]的时候,也被限定给到这一行)。计算完该行之后进入下一行,计算环境又变成了“第二行”,再计算一次,直到计算完所有的行。
这里计算公式计算到哪一行的时候,就被“当前行”这个环境限定了,这就是隐含在内部的行上下文。
理解了行上下文,再来回头看DAX中的 EARLIER() 函数就很好理解了,因为计算的时候涉及到了两个行上下文,我得去区分它们。