引用@PowerQuery的例子并给予个人理解
X1= SUMX(FILTER('Data','Data'[订单日期]>EARLIER('Data'[订单日期])),[金额])---WRONG
X2=CALCULATE(SUM(Data[金额]),FILTER(Data,SUMX(FILTER('Data','Data'[订单日期]>EARLIER('Data'[订单日期])),[金额])))---RIGHT
X1报错原因:表被扫描前没有创建行上下文。当EARLIER/EARLIEST函数被用于新建列中,会自动创建行上下文,这是由于计算列是在现有的表上新建一个列,和表中已存的列一样,可以作为表格的行、列;图标的轴及切片器的字段使用等等,也可以使用计算列与其他表格建立关系。而当EARLIER/EARLIEST函数被用于新建度量值中,度量值如果不放到上下文环境中,它是一个孤立的公式,因此想在度量值中使用,需要人为在扫描表前创建行上下文。
解决方法:利用FLITER或者其他迭代函数在表被扫描前创建行上下文。(当定义计算列时,DAX 从表的第一行开始迭代;它创建了一个包含该行的行上下文并计算表达式。然后它移到第二行,再次计算表达式。此行为发生在表的所有行,如果表有一百万行,你可以认为 DAX 创造了一百万个行上下文来计算公式一百万次。对于当前行定位单元格,和原始数据表的列进行一对多的比较,满足筛选条件的被留下,用于计算表达式)
对于X1的报错:表扫描前不存在行上下文,因为sumx函数还未执行。这样子执行fliter函数,EARLIER函数是运行不了的。
对于X2的修正:CALCULATE函数中先执行FLITER,实现筛选,再根据筛选运算表达式。筛选中,先运行table,扫描table的每一行进行sumx的筛选程序,创造了行上下文,接下来运行sumx,从左往右运行,能够实现EARLIER函数。
【知识基础】
1.FLITER/SUMX函数计算执行顺序:在DAX函数中,绝大多数函数的执行顺序都是从左到右依次进行,例如SUMX函数SUMX(<table>,<expression>),如果table参数处使用了一个可以返回表单的表达式,则在运行时Power BI会先将这个表单表达式的结果计算出来,之后再计算expression参数部分。
2.CALCULATE函数计算执行顺序:CALCULATE函数CALCULATE(<expression>,<filter1>,<filter2>…)则很特殊,Power BI会先对后面的filter参数部分进行计算,之后才会运行expression表达式部分。