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

初识筛选上下文

任何 DAX 表达都是在上下文中计算的。上下文是公式计值的“环境”,也就是说,公式的结果始终受到环境的影响。总有两种上下文,它们分别是:筛选上下文和行上下文,统称为计值上下文

随着你对 DAX 了解的深入,会逐渐了解到“环境”和“上下文”都有着丰富的内涵,让我们先从最简单的概念开始,这篇文章让我们来认识筛选上下文

第一印象

思考这样一个非常简单的度量值:

[Sales Amount] := SUMX ( Sales, Sales[Quantity] * Sales[UnitPrice] )

你已经知道这个公式计算的内容:销售表中所有数量乘以价格的总和。你可以将这个度量值放在数据透视表中查看结果,如图所示。

不含上下文的销售金额显示了总计值

这个数字看起来平淡无奇。但是,如果你仔细想想,这个公式精确地计算了它应该计算的东西:所有销售额的总和,现在它只是一个数字。当我们使用一些列来分割它并开始深入研究时,这个数据透视表就开始变得有趣了。例如,你可以使用产品颜色列,将其放在行上,然后透视表马上就显示了一些有趣的业务信息。

销售额的总和按颜色切片

总计仍然存在,但现在它是一些更小的值的总和,每一个值,连同所有其他值,都有明确的意义。但是,如果你再仔细考虑一下,你应该注意到这里发生了一些奇怪的事情:公式没有按我们所要求的方式计算。

理解计值环境

我们假定这个公式的含义是“所有销售额的总和”。但在透视表的每个单元格中,公式并未计算所有销售额的总和,它只计算具有特定颜色的产品销售额的总和。然而,我们从未指定计算必须在数据模型的子集上发生。换句话说,该公式没有被指定是否可以处理数据的子集。

为什么公式在不同的单元格中计算不同的值?答案的确很简单:是因为 DAX 在计值表达式时所处的上下文环境。你可以把一个公式的上下文环境看作是 DAX 计算公式时所在的单元格周围的区域。

因为产品颜色位于行上,所以数据透视表中的每一行都只能看到,在整个数据库中,该特定颜色的产品子集。这是公式的周围区域提供的上下文环境,即在公式计算之前应用于数据库的一组筛选器。当公式计算所有销售金额的总和时,它不会在整个数据库中计算它,因为它无法查看所有行。当 DAX 计算产品颜色值为白色的行所使用的公式时, 只有白色产品是可见的,因此, 它只考虑与白色产品相关的销售。所以对于所有销售额总和这个度量值,当计算透视表中只显示白色产品的行时,就变成了所有白色产品销售额的总和。

公式唯一按定义方式运行的情形发生在汇总行上。在这个级别,因为没有进行筛选,所以整个数据库都是可见的

另一个示例,图中红色单元格计值的影响因素:

影响红色单元格公式计值的环境因素

任何 DAX 公式都会指定计算,但 DAX 的计算发生在计值上下文中,而上下文定义了被计算出的最终结果。公式始终相同,但结果不同,因为 DAX 根据不同的数据子集执行计算。

简单起见, 下面的示例使用了数据透视表。你也可以使用查询或在 Power BI 报表环境中定义筛选上下文,你将在后续文章中详细了解。现在,我们只使用最简单的案例,只考虑数据透视表,以便对概念有一个简化和直观的理解。

案例扩展

继续最初的案例,现在让我们把年份放在列上, 使数据透视表内容更加丰富。

销售额的总和现在被颜色和年份切片

我们已经明确了计算规则:即使公式总是相同,每个单元格都可以有不同的值,因为对透视表行和列的选择都影响了上下文。事实上,2008 年白色产品的销售额与 2007 年白色产品的销售额有所不同。而且,由于可以在行和列中放置多个字段,所以其实是行上的字段集和列上的字段集共同定义了筛选上下文。下图更加明显地说明了这一点。

行和列上的字段集共同定义了上下文环境

每个单元格有不同的值,因为行标签上有两个字段,颜色和品牌名称。行和列上的整个字段集定义了上下文。例如,上图中突出显示的单元格的上下文对应了黑色、Contoso 品牌和日历年 2007。

字段是在行上还是列上(或切片器和/或页面筛选器,或你可以通过查询创建的任何其他类型的筛选器)并不重要。所有这些筛选器都共同定义一个上下文,DAX 用其来计算公式。将字段放在行或列上只有视觉上的不同,对 DAX 的计值方式没有任何影响

让我们看看这个案例现在的全貌。我们在切片器上添加了产品类别, 并在筛选条件下的月份名称中选择了 12 月。

在典型的报告中,上下文以多种方式定义,包括切片器和筛选器

小结

有一点很清楚:每个单元格中计算的值都有一个由行、列、切片器和筛选器定义的筛选上下文。所有这些筛选条件都共同定义了上下文环境 DAX 在公式计值之前将上下文应用到模型中。此外,重要的是要知道不仅是值,而且在字段方面,不是所有的单元格都有相同的筛选器集。例如,列上的总计只包含类别、月份和年份的筛选器,但不包含颜色和品牌的筛选器。颜色和品牌的字段在行上,它们不筛选总计。这同样适用于数据透视表中的颜色分类汇总:对于这些单元格,制造商字段没有筛选器,来自行的唯一有效筛选器是颜色。

我们将这种上下文称为筛选上下文, 顾名思义, 它是筛选表的上下文。任何你编写的公式根据(DAX 用于执行其计算的)筛选上下文的不同,都将具有不同的值。这种行为虽然非常直观, 但仍需要很好的理解。

Power BI 报表中的筛选上下文

现在你已经了解了什么是筛选上下文,所以下面的 DAX 表达式应该被理解为“在当前筛选上下文中可见的所有销售额之和”:

[Sales Amount] := SUMX ( Sales, Sales[Quantity] * Sales[UnitPrice] )

稍后你将学习如何读取、修改和清除筛选上下文。到目前为止,对以下事实有充分的了解就足够了:对于透视表的任何单元格或报表/查询中的任何值,始终存在筛选上下文。想要理解 DAX 如何计算一个公式,你总是需要考虑筛选上下文

在报表环境中创建的筛选上下文还有一个名称,叫做查询上下文,Query Context,在早期的文档中比较常见,大多数情况下我们不必做如此严格的区分

创建筛选上下文的方式

从前面的例子你已经了解到创建筛选上下文最常用的一种方式,通过透视表、可视化图表、切片器和筛选器创建筛选上下文。 

此处为隐藏内容 VIP会员和付费用户可见

计算列中的筛选上下文环境

上面介绍的都是报表页环境中的筛选上下文,其实,还有一处我们经常使用但是容易忽略的环境,就是计算列中的筛选上下文。 

此处为隐藏内容 VIP会员和付费用户可见

样例文件说明

DAX 圣经第一版案例使用官方的 Contoso 数据库,你可以从这里直接下载。原理部分书中虽然没有提供单独的示例文件,你可以使用下载的文件进行练习。

 

下载面板

以上隐藏内容查看价格为2G 币,请先
注:加入 VIP 会员可享受全站权益,性价比更高。单独购买的内容长期有效,不受时间限制。

5
说点什么

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

相应的数据有吗,实操一遍加深理解

pleasureyuer
成员
pleasureyuer

“计算列中的没有任何外部筛选上下文,公式总是在整个数据库环境下计值”
这句话不太通顺,建议改一下,计算列中没有任何外部筛选上下文,公式总是在整个数据库环境下计值