从数据到信息
从信息到洞察

理解 ISFILTERED 和 ISCROSSFILTERED

这是两个非常有用的函数,可以帮助你更好地理解筛选上下文的传递。此外,对它们的学习还可以引入一个 DAX 中十分有趣的概念,即如何从 DAX 内部检测正在被计算的单元格。

认识 ISFILTERED 函数

这两个函数的用途是检测列的所有值在当前筛选上下文中是否可见,理解了直接筛选(Direct-Filter)和交叉筛选(Cross-Filter)的区别,你就理解了这两个函数的作用。

ISFILTERED

ISFILTERED ( <TableNameOrColumnName> )

返回 TRUE 或 FALSE,取决于作为参数的列是否被直接筛选,也就是说,参数列已经被放在行、列、切片器或筛选器上,并且正在对当前计值区域¹进行筛选。

当使用表作为参数时,只要表中的任意一列被直接筛选,ISFILTERED 返回 TRUE。

¹计值区域:图表的值区域,比如透视表、表格和矩阵的单元格等。

自 SSAS 2019 或 Power BI 2019 年 4 月的版本之后,ISFILTERED 可以使用表作为参数,以前的版本只支持列参数

ISCROSSFILTERED

ISCROSSFILTERED ( <TableNameOrColumnName> )

返回 TRUE 或 FALSE,取决于列是否具有经过传递的筛选或直接筛选。由此可见,对交叉筛选的判定不区分筛选条件来自自身还是其他列,你可以认为直接筛选是一种特殊的交叉筛选。

函数示例

-- 以下查询返回 FALSE
EVALUATE { CALCULATE ( ISFILTERED ( Sales ), 'Product'[Color] = "Red" ) }
EVALUATE { CALCULATE ( ISFILTERED ( Sales[Quantity] ), 'Product'[Color] = "Red" ) }
EVALUATE { CALCULATE ( ISFILTERED ( Sales[Quantity] ), Sales[Unit Price] > 10 ) }
 
-- 以下查询返回 TRUE
EVALUATE { CALCULATE ( ISFILTERED ( Sales ), Sales[Unit Price] > 10 ) }
EVALUATE { CALCULATE ( ISFILTERED ( Sales[Unit Price] ), Sales[Unit Price] > 10 ) }

实战案例

在本节中,我们感兴趣的是如何使用函数来理解筛选上下文的传递。因此,我们将创建虚构的表达式,将其作为学习 DAX 的工具,如果你用这个定义创建一个新度量值:

[CategoryFilter] := ISFILTERED ( 'Product Category'[Category])

这个简单的度量值返回应用于产品类别的 ISFILTERED 函数的结果。之后你可以创建第二个度量值,用产品颜色进行相同的测试:

[ColorFilter] := ISFILTERED ( Product[ColorName] )

如果将这两个度量值添加到透视表中,将类别放在切片器,并将颜色放在行上,结果如图所示。

类别没有被筛选,而颜色被逐行筛选,只有总计行例外

有趣的是,类别未被筛选,因为即使我们添加了切片器,我们也没有对它进行选择。另一方面,颜色总是在行上进行筛选,因为每一行都有特定的颜色,而总计不包括在内,因为总计行对应的是全部筛选上下文,不包含任何产品选择。

总计的这种特征,即不应用来自行和列的筛选器,在你想修改公式行为时非常有用,比如针对总计显示一个不同的值。事实上,ISFILTERED 可以用作透视表报表的属性检查,以便理解正在计值的单元格是否在透视表内部或者是否位于总计行,

如果现在从类别切片器中选择一些值,结果会发生变化。因为现在类别中总是有一个筛选器,如下图。事实上,即使在透视表的汇总行上,切片器引入的筛选上下文也是有效的。

切片器引入的筛选条件对总计行仍然有效

ISFILTERED 对于检测那些直接应用于某列的筛选器非常有用。但在另外一些情况下,一列不显示所有值,不是因为你正在筛选该列,而是因为你在其他列上设置了筛选器。例如,如果你筛选颜色,并计算产品品牌的数量,那么你将只得到该特定颜色产品的品牌数。当一个列因为另一列上的筛选器被筛选时,我们说该列是被交叉筛选的ISCROSSFILTERED 函数被用来检测这种情况。

如果你在数据模型中加入这两个新的度量值,检查颜色和类别的交叉筛选情况:

[CrossCategory] := ISCROSSFILTERED( 'ProductCategory'[Category] )

[CrossColor] := ISCROSSFILTERED ( Product[Color] )

你会看到这样的结果

使用 ISCROSSFILTERED 可以观察到交叉筛选的发生

你可以看到颜色是被交叉筛选的,但类别不是。对于这个现象,一个有趣的问题是“为什么类别没有被筛选?”当你筛选颜色时,你可能希望只看到特定颜色的产品类别。要回答这个问题,你需要记住类别不是产品表的列。相反,它是产品类别表的一部分,关系的方向无法实现你想要的传递方式。如果你更改数据模型,将产品表和产品类别表之间的关系设置为双向筛选,那么结果将有所不同。

启用双向筛选表明,类别被交叉筛选了, 即使没有直接筛选

在本节中,你已经看到了一些 ISFILTERED 和 ISCROSSFILTERED 的示例,使用这些示例主要出于教学演示目的,是为了更好地帮助你理解筛选上下文如何通过关系进行传递。随着 DAX 水平的提高,通过编写高级 DAX 代码,你将了解为什么这两个函数如此有用。

 

23
说点什么

1000
 
鼓掌微笑开心憧憬爱你色并不觉得吃瓜doge二哈喵喵思考笑哭捂脸悲伤大哭抓狂汗偷笑打脸捂眼黑线问号晕拜拜闭嘴衰咒骂ok作揖
5 评论数
18 被回复的评论
6 订阅评论的人数
 
查看最近回复
查看最热评论
  订阅本文评论  
最新 最旧 得票最多
提醒
成员
暮色

请问是不是某列被直接筛选,则也是被交叉筛选???

交叉.png
成员
lily

老师,附件图,isfiltered的字段被直接筛选了的话,返回true,hasonefilter 参数为行业的下一个级别,为什么行业行返回false呢?而业子类级别返回true呢?行业和行业子类都被筛选了,都有一个筛选器呢,应该都是true?

11.png
成员
CatCatLa

你好老师,为什么crosscolor总是Ture?当对category不作筛选时,只有color的直接筛选器,那么corssfilter应该返回False吧

游客
13820507101

Isfiltered : “ ……并且正在对当前单元格进行筛选。”

这样描述不妥,容易产生迷惑,究竟是参数的列被筛选,还是当前单元格被筛选。当前单元格,并不是先于交叉筛选发生前构建出来的,是诸列筛选后的交叉结果。呈现出来的,等待去用度量值去度量。因此,描述为对当前单元格进行筛选的理解是:先构建一个空白单元格,然后在这个单元格里发生一系列筛选,这种理解是前后颠倒的。当然,当前单元格也没有被筛选。

可以这么讲:当前单元格包含了某列即isfiltered 参数列或表的直接筛选,或者描述为:当前单元格背后是某列即isfiltered 参数列或表的直接筛选正在发生作用。

成员
139****3194

老师,categoryfilter度量值,虽然isfitered的是product category 的category 列,透视行标签为产品颜色,根据扩展表原理,产品表扩展表包含产品类别表所有列,所以类别表里的类别列可以被颜色筛选呀,度量结果不是返回真吗?谢谢

DAX 圣经

导读

初识 DAX

DAX 基础知识

DAX 原理

DAX 高级原理

基础函数类型

迭代函数

CALCULATE 函数

CALCULATE 调节器

基础表函数

条件判断函数

查找匹配函数

时间智能函数

统计类函数

投影函数

分组/连接函数

集合函数

其他函数