专栏名称: PowerBI战友联盟
微软 Power BI MVP BI佐罗 带你学习BI真经。
目录
相关文章推荐
51好读  ›  专栏  ›  PowerBI战友联盟

DAX 中筛选上下文的直观解释

PowerBI战友联盟  · 公众号  ·  · 2024-07-01 18:23

正文

请到「今天看啥」查看全文


本文翻译自 Marco Russo & Alberto Ferrari 的文章《Filter context in DAX explained visually》。

直播内容:Power BI 九周年及 BI 行业发展回顾与展望

内容很多,干货满满,各位小伙伴耐心看完哦。

一起来看看两位意大利老师是如何为我们解释筛选上下文的。

筛选上下文是编写良好 DAX 代码时需要理解的一个基本概念。在本文中,我们使用可视化方法描述筛选上下文,依靠图形可视化来表示当您使用报表的可视化元素、筛选器和切片器时筛选上下文中存在的不同交互。这是规划获得所需结果所需更改的第一步:可以使用 CALCULATE 函数来获得这些更改,该函数可以删除、添加和替换筛选上下文中的现有筛选器。


每个单元格都有不同的筛选上下文


报告中的每个数字都是通过在特定筛选上下文中评估 DAX 表达式生成的。相同的表达式会产生不同的结果,因为它总是在不同的筛选上下文中进行评估。因此,矩阵中的每个单元格和图表中的每个数据点都有不同的筛选上下文。

我们通过描述应用于矩阵视觉对象中一个单元格的筛选器来分析筛选上下文。下图描述了返回 8,776.54 的突出显示单元格的筛选上下文。

该单元格显示了 2019 年在美国和加拿大销售的蓝色 Contoso 产品的销售额。筛选上下文中的每个过滤器都是一个包含一个或多个列“可见”值的表。 在此示例中,有四个筛选器,每个筛选器筛选一列,并在 Brand、Color 和 Year 中筛选单个值。Country 列有两个可见值的列表,对应于切片器中的选择(Canada 和 United States)。

在筛选上下文中评估的所有表函数仅返回通过应用于筛选上下文的筛选器“可见”的行。筛选上下文以极其高效的方式筛选模型中的表。此外,只有在评估聚合或迭代器时才会“使用”筛选器。稍后,我们将看到通过使用CALCULATE 可以在执行复杂的聚合之前操纵筛选上下文,从而获得灵活性和性能方面的优势。



筛选器是一个表

第一个重要概念是,筛选上下文中的筛选器是一个包含一个或多个列的值列表的表。在上例中,切片器选择了两个国家,这些值列在相应的筛选器中。但是,即使使用数字列的运算符(如“小于”)指定筛选器,筛选器也始终以满足筛选条件的该列的现有值列表表示。例如,如果报表中的筛选器窗格的条件为净价小于 10.00,则相应的筛选器将包含满足该条件的列中的唯一值列表。筛选器中的值数量取决于列中存在的唯一值。

我们知道,表示筛选上下文的更直观的方法是编写定义筛选器的筛选条件。在上图中,我们可能会倾向于写“< 10.00”,而不是满足 Net Price 条件的唯一值列表。这样做虽然可行,但只能在一定程度上奏效。事实上,对于更复杂的筛选器,如果不使用这种表示,就无法描述结果。



获取目标筛选上下文

编写计算时,通常可以在同一个视觉对象或不同的视觉对象中显示计算中涉及的所有数字。报告中的每个数字都是在特定筛选上下文中执行度量值计算的结果。每当我们需要该数字时,我们只需在该筛选上下文中计算该度量值即可。因此,在编写 DAX 公式之前,最好先描述计算中涉及的每一项的筛选上下文。

例如,考虑 % of Color 度量值的要求,该度量值返回每种颜色的销售额百分比。下图显示了在仅筛选两个国家( Canada 和 United States )时 Contoso 品牌中每种颜色的百分比。在编写任何 DAX 代码之前,我们可以用英语描述这个计算,即颜色的销售额(Contoso 品牌中的蓝色产品为 11,791.62)与所有颜色的销售额(Contoso 品牌中所有产品颜色为 202,753.05)之间的除法。在下图中,我们强调了这次除法的分子和分母,描述了每个项的筛选上下文。

我们可以将颜色百分占比度量值写为两个度量值(销售额和所有颜色销售额)之间的比值。

% of Color =DIVIDE (    [Sales Amount],    [Sales All Colors])


移除筛选器

通过比较两个筛选上下文,我们可以更改初始筛选上下文(分子)以获取目标筛选上下文(分母),然后计算所需的度量。例如,颜色百分占比度量值具有与除法的分子相对应的初始筛选上下文。此筛选上下文有三个筛选器:Blue、Contoso 品牌、 Canada 和 United States 。目标筛选上下文只有两个与初始筛选上下文(品牌和国家/地区)没有区别的过滤器。它们之间的唯一区别是 Color 过滤器,它在目标筛选上下文中不存在。

我们可以通过从初始筛选上下文中删除 Color 筛选器来获取Sales All Colors 的目标筛选上下文。通过使用 CALCULATE ,初始筛选上下文被临时复制,然后 REMOVEFILTERS 从 Product[Color] 中删除筛选器,最后在修改后的筛选上下文 中计算 Sales Amount 度量值。

也可以使用 ALL 代替 REMOVEFILTERS,它们在 CALCULATE 中的行为相同,但我们更喜欢使用 REMOVEFILTERS ,因为它可以更好地描述在筛选器上下文中执行的操作的语义:筛选器被删除,而不是用列中存在的所有值的列表替换。



添加筛选器

我们已经了解了如何删除筛选器以获取目标筛选器上下文。在其他情况下,我们必须添加初始筛选器上下文中不存在的筛选器。请记住,添加筛选器通常会减少要聚合的行数,从而在对值求和时产生较小的数字。这在开始时可能是违反直觉的,因为我们“添加”筛选器来“减少”结果!

例如,考虑我们必须实现的Sales Contoso度量值中将每种产品颜色的销售额与 Contoso 产品的相应销售额进行比较的要求。销售额的初始筛选上下文只有一个颜色筛选器。我们只需在 CALCULATE 中为 Sales Contoso 编写一个筛选条件,即可在 Product[Brand] 上添加一个筛选器。

Sales Contoso =CALCULATE (    [Sales Amount],    'Product'[Brand] = "Contoso")

虽然过滤条件是一个表达式,但我们在目标筛选上下文中得到的是一个按品牌筛选的值列表的表,在本例中仅为 Contoso。

只要应用于筛选上下文的筛选器描述了筛选上下文未直接筛选的列的条件,筛选条件就只是添加了一个筛选器。但是,如果筛选器已经存在,则我们应注意可能需要删除现有的筛选器。



修改筛选器

另一种情况是将筛选上下文中的现有筛选器替换为不同的筛选器。例如,在下面的报告中,我们想使用 2017 年作为基准,比较各个国家几年来的销售额变化情况。2017 年销售额比值度量值将一年的销售额除以 2017 年的销售额。与我们在前面的示例中看到的类似,我们可以将基准 2017 度量值比值写为两个度量值之间的比值。
Benchmark 2017 =DIVIDE (    [Sales Amount],    [Sales 2017])

当我们将初始筛选上下文(分子)与目标(分母)进行比较时,我们意识到应该用 2017 替换年份的现有过滤器。

CALCULATE 语法与我们在上一个示例中向筛选上下文添加过滤器时看到的语法惊人地相似。

Sales 2017 =CALCULATE (    [Sales Amount],    'Date'[Year] = 2017)

确实, CALCULATE 中的筛选器参数将针对年份 2017 的筛选器添加到初始筛选器上下文中。但是,针对年份如 2018 的现有筛选器将被删除,因为添加到筛选器上下文的每个筛选器都会自动删除新筛选器涉及的列上的任何现有筛选器。

从 DAX 的角度来看,这就像说每次向筛选上下文添加筛选器时,同一列上的 REMOVEFILTERS 都会自动添加到同一 CALCULATE 中。因此,我们得到的结果与编写以下代码的结果相同。

Sales 2017 =CALCULATE (    [Sales Amount],    'Date'[Year] = 2017,    REMOVEFILTERS ( 'Date'[Year] ))


将新筛选器与现有筛选器结合

在上一个示例中,自动删除现有过滤器很有用,但当我们有不同的要求时,我们可能想要更改此行为。例如,假设我们必须创建一个 Large Transactions(大额交易) 度量值,返回金额大于 1000 的交易的销售额。此过滤条件必须过滤两个销售列(数量和净价)相乘的结果,从而生成一个具有两列而不是只有一列的过滤器。但是,如果报表中已经有数量或单价的过滤器,我们不想在计算中删除它。

解决方案需要将过滤条件包装在 KEEPFILTERS 中。

Large Transactions =CALCULATE (    [Sales Amount],    KEEPFILTERS (        Sales[Quantity] * Sales[Net Price] > 1000    ))

我们可以一步一步地看到这个计算是如何进行的,并说明应用于筛选上下文的更改。

Contoso 产品的销售额的初始筛选上下文只有两个筛选器:品牌(Contoso)和净价。 CALCULATE 中的 Sales[Quantity] * Sales[Net Price] > 1000 条件向筛选上下文(数量和单价)添加了一个包含两列的筛选器。 KEEPFILTERS 的存在阻止了对单价的现有筛选器的删除,否则新筛选器会删除该筛选器。



结论


使用筛选上下文的图形表示有助于规划使用 CALCULATE 进行的计算的实施,以及描述现有计算的行为。虽然引擎可能会使用优化来避免每个筛选器的实际实现,但这种在筛选上下文中表示筛选器的方式可以解释筛选上下文操作的每个极端情况。

我们可以使用 CALCULATE 删除、添加和替换筛选上下文中的筛选器。本文的目标是提供筛选上下文的另一种视角,但 没有比在自己的数据上练习更好的学习方法了。

数据分析精英都会遇到的二十大分析问题

分析师必看: 业财人面临的二十大数据分析问题

数据分析精英都在学习的五大能力境界


分析师必备: 业务数据分析能力五层成熟度路线图框架全解


↓ 数据分析精英正在学习的课程 ↓

他们是:企业老板,高管,CFO,分析...
可以体验百万级真实企业项目案例,彻底打通任督二脉

数据分析师训练营 课程表

课程: 《业财分析之道》 业务财务人数字化能力必修课 🔥 🔥 🔥
2024年7月 满
2024年8月 少量席位

🎓 更多热门课程推荐👇👇👇

🚀 《业财分析之道》 业务财务人数字化能力必修课
📈 《经营分析之道》 企业指标拆解及经营分析框架

🔍 数据分析之道 精通分析十大方法加十大模型
💡
PowerBI 真经 更专业更系统化学习 Power BI

🔗 如何获取更多信息?扫描下方二维码具体咨询。

如果您觉得这篇文章对您有帮助或启发
感谢您【点赞】、【在看】
如果您需要添加老师,也请先 【点赞】、【在看】

这样老师才能更快地识别并回应

跟BI佐罗老师更专业更系统学企业数据分析
点击“阅读原文”获取更多资源







请到「今天看啥」查看全文