为了便于在公式内部操作模型关系,DAX 提供了两个非常有用的函数:RELATED 和 RELATEDTABLE.
你已经知道,计算列可以在定义它的表中引用列值,因此,在销售表中定义的计算列可以引用所在表的任何列。但是,如果必须引用另一个表中的列,该怎么办呢?通常,除非模型中定义了两个表之间的关系,否则不能使用其他表中的列。如果两个表建立了关系,那么可以使用 RELATED 函数访问相关表中的列。
从关系的多端访问一端
例如,你可能希望在销售表中定义这样一个计算列,该列检查已销售的产品是否属于“手机”类别,当满足条件时,适当缩减标准成本。要计算这样一个列,你必须使用一个条件来检查产品类别的值,该值不在销售表中。然而,模型中的关系链从销售表开始,通过产品表和产品子类别表到达产品类别表,如下图所示。
从原始表到目标表之间需要经过多少步并不重要,DAX 将遵循完整的关系链,并返回相关列值。因此,可调整成本(AdjustedCost)列的公式为:
Sales[AdjustedCost] = IF ( RELATED ( 'Product Category'[Category] ) = "Cell Phone", Sales[UnitCost] * 0.95, Sales[UnitCost] )
在一对多关系中,RELATED 可以从多端访问一端,因为在这种情况下,关联表中只有一行(如果有的话)。如果不存在满足条件的行,RELATED 返回空。
从关系的一端访问多端
如果你希望从关系的一端访问多端,那么 RELATED 就不适用了,因为另一端(关系的多端)可能存在许多行对单个行可用。在这种情况下,可以使用 RELATEDTABLE。RELATEDTABLE 返回一个表,其中包含与当前表相关的所有行。例如,如果你想知道每个类别中有多少个产品,你可以使用以下公式在产品类别表中创建一个列:
COUNTROWS ( RELATEDTABLE ( Product ) )
此计算列将显示每个产品类别的相关产品数量,如图所示。
就像 RELATED 一样,RELATEDTABLE 沿着模型关系链,总是从一端指向多端。
上下文转换与关系函数
关系函数需要一个活动的行上下文才能生效。如果移除计算列的行上下文,那么它们将不再工作。例如,下面的计算列会报错,因为 CALCULATE 执行上下文转换移除了行上下文:
Sales[Wrong] = CALCULATE ( RELATED ( Product[Product Name] ) )
当你学习了扩展表的概念之后,会了解到扩展表包含了关系。实际上,关系就是在扩展表中运行的,一旦你开始用扩展表的方式思考,就不再需要考虑关系了。在刚开始学习 DAX 的当前阶段,我们对 RELATED 的认知是它允许访问相关表中的列。更准确的理解是,RELATED 允许你访问扩展表的相关列。
扩展阅读:
Related函数只能做计算列,无法做一个度量值吗?
“关系函数需要一个活动的行上下文才能生效” — RELATED和RELATEDTABLE 都可作为关系函数,但对于 RELATEDTABLE 而言,它也可以用作 CALCULATETABLE 的简化版,此时不需要行上下文也能正常运作。但这时的RELATEDTABLE 就不应解读为关系函数,作者也不推荐这样使用
讲到函数突然就觉得轻松些了,基础原理真的好绕脑子啊
之前在使用Filter函数时,需要根据其类别进行判断,比如A表的门店ID与B表的门店ID对应的类型有关系,那么使用Filter就无法从B表的分类中选择A表对应的内容,如果使用RELATED则完美的解决了这个问题。
直营门店数量 =
sumx(
FILTER(
‘库存’, — 该表中无门店类型,使用该表门店ID与B表门店ID关联,门店类型在B表
RELATED( ‘D_门店'[门店类型] ) = “直营”
),
[数量]
)
如果行上下文只在计算列和迭代函数中存在,而在数据透视表中不存在,那么这样的一个度量值 countrows(relatedtable(sales)) 为什么可以在数据透视表中使用呢?如果数据透视表中存在行上下文,那么度量值 countrows(filter(calender,date=earlier(date))) 中的earlier 为什么找不到上一层的行上下文呢?
谢谢?
“关系函数需要一个活动的行上下文才能生效”——是不是意味着关于Related和RelatedTable能且仅能在计算列中使用?度量值中不能用呢?