PowerBI/DAX之理解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函数时需要考虑清楚所有条件才行,否则很容易就会出现错误。

<think>好的,我现在需要回答用户的问题:“在powerbi DAX函数中筛选器的区别”。首先,我需要回忆DAX中常见的筛选器函数,比如FILTER、ALL、ALLEXCEPT、ALlSELECTED、USERELATIONSHIP、CROSSFILTER等,以及它们的作用和区别。用户可能想了解这些函数在应用筛选时的不同行为,比如是否移除上下文、影响哪些表或列、如何修改关系方向等。 首先,我需要明确DAX中的筛选器函数主要用于控制数据上下文,影响计算结果。常见的筛选器函数可以分为几类:移除筛选的函数(如ALL、ALLEXCEPT)、应用筛选的函数(如FILTER)、处理上下文的函数(如ALlSELECTED)、以及管理关系的函数(如USERELATIONSHIP、CROSSFILTER)。 接下来,我需要逐一解释这些函数的作用、语法和使用场景,并对比它们的区别。例如,ALL函数会移除指定表或列的所有筛选,而ALLEXCEPT则保留指定列的筛选,移除其他列的筛选。FILTER函数则是在现有上下文中应用新的筛选条件,返回符合条件的行。ALlSELECTED通常用于处理用户交互中的筛选,考虑所有选中的筛选器,包括页面、切片器等。USERELATIONSHIP和CROSSFILTER则用于临时更改关系的激活状态或方向。 需要注意用户可能混淆的点,比如ALL和ALLEXCEPT的区别,FILTER与CALCULATE中筛选参数的关系,以及ALlSELECTED在视觉对象上下文中的行为。此外,还要举例说明不同函数的使用场景,帮助用户理解何时选择哪个函数。 最后,确保回答结构清晰,先总述筛选器函数的作用,再分类型详细解释每个函数的区别,最后总结应用场景。同时,按照用户要求,在回答末尾生成3-5个相关问题。 </think>在 Power BI 的 DAX 函数中,**筛选器函数**主要用于控制数据上下文(行上下文或筛选上下文),影响计算结果的范围。不同筛选器函数的核心区别在于 **对现有筛选的处理方式**(如移除、保留、修改)、**作用对象**(表、列、关系)以及 **应用场景**(计算、上下文转换等)。以下是常见筛选器函数的详细对比: ### **一、移除筛选的函数:ALL、ALLEXCEPT、ALLSELECTED** 这类函数用于清除或限制现有筛选上下文的影响,常用于计算“总计”或“不受部分筛选影响”的值。 | 函数 | 核心作用 | 关键区别 | 典型场景 | |--------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------| | `ALL(<表或列>)` | 移除指定表或列的**所有筛选**(包括行上下文和筛选上下文)。若不指定参数,移除整个表的筛选。 | 完全清除筛选,仅保留原始数据(无任何筛选条件)。 | 计算“全局总计”(如“所有地区的总销售额”,忽略切片器对地区的筛选)。 | | `ALLEXCEPT(<表>, <列1>, <列2>, ...)` | 移除表中**除指定列外**的所有筛选(仅保留指定列的筛选)。 | 选择性保留部分列的筛选,其他列的筛选被清除。 | 计算“按特定维度分组的总计”(如“保留地区筛选,但清除产品类别的筛选”)。 | | `ALLSELECTED(<表或列>)` | 移除**用户交互外的筛选**(保留页面/视觉对象中用户主动选择的筛选,如切片器、交叉筛选)。 | 仅清除“隐式筛选”(如计算列或行上下文的筛选),保留用户显式交互的筛选。 | 计算“与用户交互一致的总计”(如“当前选中的产品类别下,所有地区的总销售额”)。| #### **示例对比** 假设表 `Sales` 包含 `地区`、`产品类别`、`销售额` 列,且页面切片器筛选了“地区=华北”: - `ALL(Sales)`:忽略“地区=华北”的筛选,计算所有地区的总销售额。 - `ALLEXCEPT(Sales, 产品类别)`:保留“产品类别”的筛选(若有),但清除“地区”的筛选(包括切片器的“华北”筛选),计算各产品类别在所有地区的总销售额。 - `ALLSELECTED(Sales)`:保留切片器“地区=华北”的筛选(用户显式选择),计算华北地区的总销售额(若其他隐式筛选存在则清除)。 ### **二、应用筛选的函数:FILTER** `FILTER(<表>, <逻辑表达式>)` 用于在现有上下文中**应用新的筛选条件**,返回符合条件的行组成的表。与直接在 `CALCULATE` 中使用筛选参数不同,`FILTER` 通常作为参数传递给其他函数(如 `SUMX`、`CALCULATE`)。 #### **核心区别** - **与 `CALCULATE` 直接筛选的对比**:`CALCULATE` 会直接修改筛选上下文(覆盖或添加筛选),而 `FILTER` 仅返回一个子集表,需结合迭代器(如 `SUMX`)或 `CALCULATE` 使用。 - **行上下文与筛选上下文**:`FILTER` 内部使用行上下文(逐行判断逻辑表达式),而 `CALCULATE` 直接操作筛选上下文(列级别的筛选)。 #### **示例** 计算“产品类别=电子”且“销售额>1000”的订单数量: ```dax 电子高销售额订单数 = COUNTROWS( FILTER( Sales, Sales[产品类别] = "电子" && Sales[销售额] > 1000 ) ) ``` ### **三、管理关系的筛选器:USERELATIONSHIP、CROSSFILTER** 这类函数用于临时修改模型中的关系(如激活非活动关系、调整筛选方向),仅在 `CALCULATE` 或 `CALCULATETABLE` 中生效。 | 函数 | 核心作用 | 关键区别 | 典型场景 | |---------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------| | `USERELATIONSHIP(<列1>, <列2>)` | 强制使用指定的列对建立关系(即使模型中该关系未激活)。 | 仅激活一对列之间的关系,其他关系保持原样。 | 当模型中存在多对关系(如同一对表有多个关联列),需指定使用某一特定关系。 | | `CROSSFILTER(<列1>, <列2>, <方向>)` | 修改指定关系的筛选方向(单向/双向/无)。 | 动态调整关系方向(默认单向:从一方到多方)。 | 解决双向筛选导致的循环依赖(如两个维度表互相影响),或临时启用双向筛选。 | #### **示例** 假设模型中 `订单表` 与 `日期表` 有两个关系(`订单日期` 和 `发货日期`),默认激活 `订单日期`,但需按 `发货日期` 筛选: ```dax 发货日期销售额 = CALCULATE( SUM(订单表[销售额]), USERELATIONSHIP(订单表[发货日期], 日期表[日期]) ) ``` ### **总结:如何选择筛选器函数?** - 若需**清除筛选**:用 `ALL`(完全清除)、`ALLEXCEPT`(保留部分列)、`ALLSELECTED`(保留用户交互筛选)。 - 若需**应用新筛选**:用 `FILTER`(结合迭代器或 `CALCULATE`)。 - 若需**管理关系**:用 `USERELATIONSHIP`(激活非活动关系)、`CROSSFILTER`(调整筛选方向)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PowerBI | 夕枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值