DAX 第二篇:概述计算上下文

计算上下文是DAX表达式求值的环境,任何DAX表达式都是在上下文中求值的。行上下文和筛选上下文是DAX中仅有的上下文类型,把这两种上下文称为计算上下文。计算上下文用于限定公式计算的环境,当上下文变化时,相同的公式会计算出不同的结果。

在PowerBI中创建的计算列是在行上下文中执行计算,创建的度量(meassure)是在筛选上下文中执行计算。

  • 行上下文是一个总是包含一行的上下文,DAX在创建计算列时自动定义行上下文。
  • 筛选上下文是由切片器(Slicer)、用户选择的分组字段、关系的筛选方向等过滤器共同定义的,而DAX利用筛选上下文来计算公式(度量)。

一,行上下文

行上下文仅仅存在于表的同一行中,作用是对表中同一行的不同列,对同一行的不同列应用公式,逐行计算出公式的结果。

例如,创建一个计算列 Profit,利润的公式是由商品的   销售额 - 税额 - 成本 - 运费,DAX公式如下所示:

Profit = FactSales[SalesAmount]-FactSales[TaxAmt]-FactSales[TotalProductCost] - FactSales[Freight]

DAX逐行应用公式,对于表中每一行,都会根据公式,把同一行上的不同列的值代入到公式中,计算出公式的结果:

实际上,用于执行计算的行并没有存储在公式中,而是定义在行上下文中。从逻辑的角度来讲,计算列的工作流程是:

  • 当你定义计算的列时,DAX从表的第一行开始迭代,首先创建了包含该行的行上下文并对表达式求值,
  • 然后它移到第二行,再次求出表达式;
  • 这发生在表格中所有的行中,如果你有100万行,你可以认为DAX创建了100万行上下文来评估这个公式100万次。

二,筛选上下文

创建的度量在筛选上下文中执行公式的计算,筛选上下文是对表应用过滤器之后,数据被筛选之后的上下文。筛选上下文是由过滤器共同作用的,过滤器主要有:切片器(Slicer),查询上下文和关系。DAX的强大之处在于,DAX不仅能够自动应用筛选上下文,还支持修改、清除和重定义筛选上下文。
1,自动应用筛选上下文
在PowerBI的FactSlaes表中定义一个度量,用于计算总的销售额:
Measure SumOfAccount = CALCULATE(SUM(FactSales[SalesAmount])) 

为该度量增加一个分组列FullName,可以看到,这个分组列对度量的上下文进行过滤,使其只能计算每个FullName对象的销售额,而度量自动应用筛选之后的上下文,计算每个FullName的销售额:

FullName是DimCustomers表的字段,该字段能够自动过滤FactSales表的原因是在数据模型中,表DimCustomers和表FactSlaes之间存在关系,并且关系的方向是由DimCustomer指向FactSales,这说明,DimCustomers可以过滤FactSales:

2,关系的方向

当关系的方向是由A指向B时,说明A可以筛选B,而B不能用来筛选A。上图中,表DimCustomers和表FactSlaes之间存在关系,并且关系的方向是由DimCustomer指向FactSales,这说明,DimCustomers可以过滤FactSales。我们来测试一下,FactSales是否可以筛选DimCustomers?创建一个新的度量,测试使用FactSales的ProductKey来统计用户的数量:

Measure CountCustomer = CALCULATE(COUNT(DimCustomers[CustomerKey])) 

测试的结果是 Measure CountCustomers的值是DimCustomers表的总数量,也就是说,ProductKey不能过滤DimCustomers表。

当把DimCustomer和FactSales之间的关系修改为双向时:

用于FactSales可以过滤DimCustomers,DAX自动应用筛选上下文,统计每个ProductKey对应的客户数量:

3,修改、清除和重定义筛选上下文

使用DAX函数可以修改、清除和重定义筛选上下文。CALCULATE()函数是DAX中最复杂的函数,用于计算由指定过滤器修改的上下文中的表达式。
CALCULATE(<expression>,<filter1>,<filter2>…) 

 第一个参数是用于计算聚合值的度量,后面的参数是可选的过滤器,共有两种类型:

  • 返回布尔值的逻辑表达式
  • 返回表的表达式

CALCULATE函数的复杂之处在于可变的数据上下文。如果数据已被过滤,则CALCULATE函数会更改过滤数据的上下文,并在您指定的新上下文中计算表达式。 对于filter参数中使用的每个列,将删除该列上的任何现有过滤器,并应用filter参数中使用的过滤器。

 

 

参考文档:

DAX Context

【DAX圣经】第四章:理解计算上下文(1)

详解CALCULATE系列-基础篇

posted @ 2019-07-19 13:30  悦光阴  阅读(3148)  评论(0编辑  收藏  举报