[知识体系] 初识筛选上下文

  [复制链接]
查看92169 | 回复110 | 2021-2-21 19:34:06 | 显示全部楼层 |阅读模式
任何 DAX 表达都是在上下文中计算的。上下文是公式计值的“环境”,也就是说,公式的结果始终受到环境的影响。总有两种上下文,它们分别是:筛选上下文和行上下文,统称为计值上下文


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

思考这样一个非常简单的度量值:
  1. [Sales Amount] := SUMX ( Sales, Sales[Quantity] * Sales[UnitPrice] )
复制代码

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


7151211936391.jpeg

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


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


7151211936392.jpeg

销售额的总和按颜色切片


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

理解计值环境

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


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


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



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


7151211936393.jpg

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


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


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

案例扩展

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


7151211936394.jpeg

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


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


7151211936395.jpeg

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


每个单元格有不同的值,因为行标签上有两个字段,颜色和品牌名称。行和列上的整个字段集定义了上下文。例如,上图中突出显示的单元格的上下文对应了黑色、Contoso 品牌和日历年 2007。
字段是在行上还是列上(或切片器和/或页面筛选器,或你可以通过查询创建的任何其他类型的筛选器)并不重要。所有这些筛选器都共同定义一个上下文,DAX 用其来计算公式。将字段放在行或列上只有视觉上的不同,对 DAX 的计值方式没有任何影响



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


7151211936396.jpeg

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

小结



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


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


Power BI 报表中的筛选上下文


现在你已经了解了什么是筛选上下文,所以下面的 DAX 表达式应该被理解为“在当前筛选上下文中可见的所有销售额之和”:
  1. [Sales Amount] := SUMX ( Sales, Sales[Quantity] * Sales[UnitPrice] )
复制代码

稍后你将学习如何读取、修改和清除筛选上下文。到目前为止,对以下事实有充分的了解就足够了:对于透视表的任何单元格或报表/查询中的任何值,始终存在筛选上下文。想要理解 DAX 如何计算一个公式,你总是需要考虑筛选上下文
在报表环境中创建的筛选上下文还有一个名称,叫做查询上下文,Query Context,在早期的文档中比较常见,大多数情况下我们不必做如此严格的区分


创建筛选上下文的方式

从前面的例子你已经了解到创建筛选上下文最常用的一种方式,通过透视表、可视化图表、切片器和筛选器创建筛选上下文。 值得注意的是,透视表和图表在初始状态下创建的是静态的筛选上下文,而报表层的交互操作可以新增或修改已有的上下文环境。比如


  • 调整筛选器取值范围
  • 图表之间的联动
  • 层级钻取
  • 页面钻取


除去上面这种最常见的方式,筛选上下文还有一种更重要的创建方式,就是通过 CALCULATECALCULATETABLE 在公式内部编程式的创建筛选上下文,使用这种方式,你可以调整报表层的筛选环境,调整公式的计值行为,以及借助上下文转换引入更多的筛选条件。毫不夸张的说,能否熟练运用 CALCULATE 决定了使用者的 DAX 水平,这部分内容我们将在 CALCULATE 函数一节中详细介绍。

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

上面介绍的都是报表页环境中的筛选上下文,其实,还有一处我们经常使用但是容易忽略的环境,就是计算列中的筛选上下文。 当你需要创建计算列的时候,理解它所处的筛选上下文环境是非常有必要的,简单的说,计算列中没有任何外部筛选上下文,公式总是在整个数据库环境下计值,你可以参考本文使用的第一幅图。
这个概念虽然基础,但是却非常重要,因为随着你学习了 CALCULATE 和上下文转换的知识后,计算列所用公式的筛选上下文可以变的非常复杂,明确公式的初始环境是理解 DAX 计值流的基础


样例文件说明

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

使用道具 举报

树洪 | 2021-4-24 19:13:01 来自手机 | 显示全部楼层
忙完了,来看看视频
回复

使用道具 举报

小树 | 2021-5-3 15:08:58 来自手机 | 显示全部楼层
努力学习中
回复

使用道具 举报

yangzi1985 | 2021-6-15 14:21:53 | 显示全部楼层
我也来顶一下..
回复

使用道具 举报

德军1941 | 2021-8-20 07:44:41 | 显示全部楼层
大人,此事必有蹊跷!
回复

使用道具 举报

六只翅膀 | 2021-9-14 15:00:44 来自手机 | 显示全部楼层
发发呆,回回帖,工作结束~
回复

使用道具 举报

草莓妹 | 2021-9-17 17:01:31 | 显示全部楼层
OMG!介是啥东东!!!
回复

使用道具 举报

痴心de绝对 | 2021-10-28 12:13:59 | 显示全部楼层
我只是路过,不发表意见
回复

使用道具 举报

雕心 | 2021-10-30 09:45:01 | 显示全部楼层
支持,赞一个
回复

使用道具 举报

pphose | 2021-11-5 22:10:44 | 显示全部楼层
LZ是天才,坚定完毕
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则