回忆是一座桥
却是通往寂寞的牢

29、理解USERELATIONSHIP函数

在模型关系中,两个表之间只能存在一条激活的关系,激活的关系会使用实线来呈现,而当连接多条关系时,从第二条关系开始的其它关系都会自动变成虚线,即未激活状态,如下图所示:

在DAX表达式进行计算的时候,默认使用的是激活的关系,未激活的关系并不起作用,可以被忽略,但可以使用USERELATIONSHIP函数来临时激活这些虚线关系,使其变成激活的状态。由于两个表之间只能存在一个激活的关系,因此当一个未激活的关系被激活时,会使原来的激活关系变成未激活的状态。

由于模型关系非常重要,牵一发而动全身,改变关系时会影响到所有度量值的计算。因此在某些需要改变关系连接字段的特殊场景下,可以使用USERELATIONSHIP函数来临时激活这些虚线关系,在满足需求的同时,又能缩小影响范围。


USERELATIONSHIP函数的语法结构与作用

语法:

USERELATIONSHIP(<columnName1>, <columnName2>)

USERELATIONSHIP函数的两个参数代表了一条模型关系在两端的连接字段,只能使用基础列,而且必须使用完全限定性的写法。<columnName1>通常表示位于多端的连接字段,<columnName2>则表示位于一端的连接字段,但即使颠倒了顺序也无妨,该函数会自动调整成正确的顺序,因为USERELATIONSHIP函数针对的是现有的关系,所以能够清楚的知道连接字段分别来自哪一端。

作用:

USERELATIONSHIP函数属于筛选调节器,可以在CALCULATE函数的计算过程中临时指定需要使用的表间关系,若指定的关系处于未激活状态,则该关系将被激活,若两表之间激活的关系超过两条,将使原来的激活关系变成未激活的状态,效果持续至其所在的CALCULATE函数计算完成。需要注意,该函数的作用对象是现有的模型关系,因此两个参数指定的连接字段若不能指代一个存在的关系,或者指定的连接字段属于不同的关系,则会报错。


USERELATIONSHIP函数的应用

如下图所示,日期表与订单表之间有两条关系,其中处于激活状态的是与订单日期相关联的关系,与发货日期进行关联的关系则处于未激活状态,因此,矩阵中统计的是每天的总订购数量。

此时,假如想要分析每天的总发货数量,那么则需要把激活关系更改为与发货日期连接的关系才行,但这样做很可能会影响到其它已有度量值的结果。因此,想要在不改变模型物理关系的前提下计算出每天的总发货数量,那么可以采用传统的筛选转移的方式进行计算,如下图所示:

以上筛选转移的方法并没有任何问题,但在掌握了USERELATIONSHIP函数后,还可以在计算时临时激活与发货日期相关联的日期,从而使日期表的日期含义变为发货日期,进而计算出每天的总发货数量。具体写法如下图所示:

其中,USERELATIONSHIP函数的写法更简洁,而且从性能上来看的话,USERELATIONSHIP函数的方案也会更快,通过性能分析器可以很清楚的观察到这一点,如下图所示:

可以明显看到,在多次计算下,USERELATIONSHIP方案的计算时间总是快四分之一左右,这在数据量级比较大的情况下差距将更大。


深入理解USERELATIONSHIP函数

在应用USERELATIONSHIP函数时,需要注意:USERELATIONSHIP函数只修改关系,不影响现有的任何筛选器,但由于关系的改变,筛选器筛选的列的含义可能会发生改变,但筛选的值并不会变。

为了能够更好的掌握USERELATIONSHIP函数,下面对该函数的一些细节进行举例说明。

假如现在想要计算当天订购当天发货的数量,也就是需要找出那些订购日期与发货日期一致的订单,然后再汇总数量,按照这个思路可以得到以下解决方法,如下图所示:

上面是传统的解决方法,其核心思路就是在矩阵行标签筛选后的当天数据中,再次过滤出订购日期与发货日期相等的那部分数据,筛选器都是明晃晃的,比较好理解。

下面来看一下USERELATIONSHIP函数的解法,如下图所示:

这个解法看起来也是很简洁的,但可能比较难以理解,因为订购日期与发货日期相等的这个条件藏得非常隐蔽。那么下面就来分析一下这个表达式的计值流程,进而帮助理解USERELATIONSHIP函数的行为与作用。

首先,矩阵行标签提供了一个日期表上的日期筛选器,而且激活的关系是与订购日期相连接的,也就是说日期表上的这个日期筛选器筛选的是订购日期。另外,在CALCULATE函数中有两个内部筛选器,其中一个是筛选调节器,即USERELATIONSHIP函数,另一个则是普通的内部筛选器,即订单表,由于订单表是基础表,因此还要考虑订单表的扩展表。

然后,按照CALCULATE函数的计值流程,第一步是先在外部计值环境中计算各个内部筛选器,但并不应用,其中各个内部筛选器的计算互相独立,互不影响。那么此时,订单表这个内部筛选器由于是在外部计值环境中计算的,不受USERELATIONSHIP函数的影响,所以订单表的计算还是使用的与订购日期相连接的关系,因此订单表的扩展表上属于日期表的那部分日期将与订购日期一致,此时订单表的扩展表如下图所示:

然后,USERELATIONSHIP函数作为筛选调节器会优先应用,将模型关系更改为与发货日期相关联的那个关系,因此订单表内部筛选器将在更改后的模型关系上进行筛选。此时需要注意,由于模型关系的改变,日期表上的日期筛选器将不再筛选订购日期,而是筛选发货日期,即筛选的列的含义发生了变化,但它筛选的值还是一样的,即如上图所示的那样,每一行的日期都与订购日期相等。

简单来说就是,现在日期表上的这个日期筛选器筛选的含义是发货日期,而筛选的值却与订购日期相同,因此可以过滤出订购日期与发货日期相等的那部分数据,从而能够计算出当天订购当天发货的数量。

这也就是之前提到的,USERELATIONSHIP函数只修改关系,不影响现有的任何筛选器,但由于关系的改变,筛选器筛选的列的含义可能会发生改变,但筛选的值并不会变,理解了这一点,那么USERELATIONSHIP函数就算是掌握了。


总结

USERELATIONSHIP函数的作用很简单,就是在CALCULATE函数的计算过程中临时更改关系,除此之外,其它内容等都没有变化。但是,由于该函数更改的是模型关系,而模型关系是计值环境的重要组成部分,因此还涉及到了扩展表、筛选器交互与传递、计值上下文等内容,从而使得复杂性成倍上升。因此,在使用USERELATIONSHIP函数时需要考虑清楚所有条件才行,否则很容易就会出现错误。

未经允许不得转载:夕枫 » 29、理解USERELATIONSHIP函数
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论