DAX从入门到精通 5-1-2 介绍calculate

calculate以及calculatetable是DAX中唯一能修改筛选上下文的函数。calculate会建立一个新的筛选上下文,然后,表达式会在新的上下文环境中计算。因为相对于已经存在的上下文,表达式的中的上下文我们称为新的上下文。

Calculate的语法:

[Measure] := CALCULATE ( Expression, Condition1, ...
ConditionN )

calculate可以接受任意数量的参数,但是只有第一个参数是必须的。也就是计算的表达式。我们称跟随在第一个参数后面的参数为条件表达式。calculate是这样工作的:

  • 它会对现有的筛选上下文条件建立一个副本,然后添加到新筛选上下文中。
  • 它对每个过滤条件,都生成一个列,作为筛选条件。
  • 如果两个或者更多的参数作用于同一个列,那么他们会以AND的形式合并起来(可以理解为取并集)
  • 它是使用新的筛选条件替换现有的列的筛选条件,如果已经存在了筛选器,那么新的条件会替代已经存在的。另外,如果列没有筛选器,那么DAX会对列添加一个新的筛选器。
  • 一旦新的筛选条件应用了,那么calculate就开始在这个条件下计算结果,最后显示结果,并且还原该单元格的筛选上下文。

重点:
calculate还有另外一个非常重要的特性,就是把行上下文转换为筛选上下文。本章节的后面,我们会进一步的讨论这个问题。这里提到这个特性,是想预先给你一个印象,让你记得calculate自动转换行上下文为筛选上下文。

calculate接受两种类型的过滤参数:

值列表形式,用表表达式的方式。这种情况下,我们提供了一个列表作为新的筛选上下文。可以是一个单列的表或者多列的表。例如你要过滤整个表。

布尔值。例如Product[Color] = “White”,这种写法只能针对一个列,因为结果必须是一列中的某些值。

如果你使用的布尔值的写法,那么DAX会把它转换为一个列表的值,所以当你这样写:

[Sales Amount Red Products] :=
CALCULATE (
SUM ( Sales[SalesAmount] ),
Product[Color] = "Red"
)

DAX会转换为下面这样的写法:

[Sales Amount Red Products] :=
CALCULATE (
SUM ( Sales[SalesAmount] ),
FILTER (
ALL ( Product[Color] ),
Product[Color] = "Red"
))

所以,你只能在每个参数中对一个列使用一个布尔表达式。DAX会对整个列进行过滤迭代,这个后台会自动执行。如果要用布尔表达式处理多个列,那么你要在filter函数中用特别的写法,后面会介绍。

这里,我们回到前面的案例中,计算销售额对所有category和subcategory的占比,但是依然要考虑color的筛选器。我们使用calculate函数。

[SalesPctWithCalculate] :=
DIVIDE (
SUM ( Sales[SalesAmount] ),
CALCULATE (
SUM ( Sales[SalesAmount] ),
ALL ( 'Product Category' ),
ALL ( 'Product Subcategory' )
))

我们来看看分母中使用的calculate函数。表达式很容易理解,sumo of sales amount.但是我们知道,根据DAX的上下文环境,一个函数可以有不同的结果。因为计算表达式是在calculate内部,所以,表达式的上下文环境就不是原始的。这样我们就要知道上下文环境是什么,而这个信息就来自于calculate函数内部的其他参数。

第一个过滤参数是使用了all函数,all函数返回了表中的所有行,在这里即是所有的category。DAX提取了product category的值并将其作为新的过滤条件,代替之前使用的任何product category的列的筛选器,本案例中,来自于透视表的行。

同样的,对于第二个参数,all(product subcategory)移除了所有作用于product subcategory上的过滤条件。

重要的部分是calculate并没有移除来自于切片器的过滤条件,也就是color。只移除了product category和product subcategory表的。因此,最后的筛选上下文包含了所有的category和subcategory,保留color。

把这个度量值应用到透视表里面,就可以看到正确的结果了。

DAX从入门到精通 5-1-2 介绍calculate_第1张图片
image.png

这里,细心的读者可能会问,这个不太合理,我们移除了来自于category和subcategory的过滤器,但是你是在sales表中求和。是谁移除了过滤器呢?很好的问题,calculate一旦得出了新的筛选上下文,那么他会在评估表达式之前将其应用于数据模型。

当DAX实施一个筛选器的时候,我们之前学过,过滤条件会通过关系传递。当新的筛选条件应用的时候,category和subcategory中原本的过滤器就会被移除,然后新的条件就会传递到事实表,也就是从category到subcategory 最后到处于多方的sales表。所以sales表相对于的过滤条件也被移除了。

你可能感兴趣的:(DAX从入门到精通 5-1-2 介绍calculate)