DAX 第四篇:行上下文
行上下文标识当前行,仅仅用于迭代,不会筛选任何数据,也不会自动利用关系。在当前的行上下文中,可以通过RELATED 和 RELATEDTABLE函数利用关系,以获取相关联表中得数据。行上下文存在于计算列或迭代函数中,没有其他方法可以创建行上下文,计算列和迭代函数会自动创建行上下文。
一,迭代函数执行迭代的过程
迭代函数对数据表执行迭代计算的过程分为两步:
第一步:过滤数据,SUMX的第一个参数是表Sales,该表受到到筛选上下文的影响,只返回过滤之后的数据行,以确定要迭代(逐行扫描)的表的范围;
第二步:执行迭代计算,SUMX的第二个参数是一个表达式 Sales[Net Price] * Sales[Discount],该表达式处于行上下文中,也就是说Sales[Net Price] 和 Sales[Discount]是同一行中的不同列,SUMX逐行计算表达式的值,并把所有的值加起来作为函数的返回值。
Sales = SUMX( Sales, Sales[Net Price] * Sales[Discount])
注意:最容易误解的一个函数是FILTER函数,它是一个迭代函数,不会修改筛选上下文,该函数受到筛选上下文的影响,并根据条件返回数据的子集。
二,行上下文和关系
在迭代过程中,行上下文迭代一个单独的表,并且只针对这个表。其他表虽然与迭代的表存在关系,但是行上下文不会随着关系传递到其他相关表上,也就是说,行上下文不会自动利用关系。在当前的行上下文中,可以通过RELATED 和 RELATEDTABLE函数利用关系,以获取相关联表中得数据。RELATED 和 RELATEDTABLE函数可以贯穿一条长长的关系链,跟关系的长度(或步数)无关。对关系的唯一限制是:所有关系都需要具有相同的类型(即一对多或对一),并且关系都朝着相同的方向。
举一个列子,嵌套多个表的行上下文,在表达式求值期间,激活了三个行上下文,即三个迭代函数分别激活了一个行上下文。两个RELATEDTABLE函数从当前行上下文中返回相关表中的数据行。
SUMX( 'Product Category',
SUMX( RELATEDTABLE('Product'),
SUMX( RELATEDTABLE('Sales'),
'Sales'[Quantity] * 'Product'[Unit Price] * 'Product Category'[Discount]
)
)
)
这段代码的性能和可读性不是最优的,嵌套的行上下文导致表达式的性能随着表的数据量增加而急剧下降,应避免使用嵌套,优化后的代码如下,在当前的行上下文中,使用RELATED函数,获取相关联表中的唯一值。
SUMX( 'Sales,
RELATED('Sales'[Quantity]) * RELATED('Product'[Unit Price]) * RELATED('Product Category'[Discount])
)
参考文档: