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

理解 TREATAS

TREATAS 函数是无关系情况下执行查找匹配的最佳选择,它通过映射数据沿袭的方式使无关系筛选成为可能,了解 TREATAS,你需要先了解关于数据沿袭的知识。

了解数据沿袭(Data Linage)

任何表函数都包含一个或多个列,每个列都具有特定的沿袭当一个列对应于数据模型的一个物理列时,引擎可以识别这种沿袭关系,从而可以更快地进行筛选操作。沿袭不取决于列的名称,从技术上讲,它是可以唯一标识列的内部标准。你无法通过 DAX 显示列的沿袭,但可以观察这种效果。

例如,观察下面这个由两个颜色值组成的匿名表

{ "Red", "Blue" }

我们知道它们代表颜色,假设你正在模型中分析相关问题,你可以更具体的理解为这是在引用产品的颜色。但对于 DAX 引擎来说,它只表示包含两个字符串的表。所以,下面的的度量值将始终得到总销售额,因为这个匿名表不能筛选模型:

Test :=
CALCULATE ([Sales Amount],{ "Red", "Blue" })
这个度量值没有任何报错,这里的筛选器参数使用了匿名表,对数据模型的物理表没有任何影响

在下图中,你可以看到结果与 Sales Amount 相同,因为 Calculate 没有应用任何进一步的筛选

使用匿名表筛选不会产生任何有效筛选

对于那些想要筛选模型的值,DAX 需要验证它的数据沿袭。一个容易理解的知识是,数据模型中的列值保有该列的数据沿袭与之相对的,如果一个值没有链接到数据模型中的任何列,那么它就是一个匿名值。在前面的示例中 Test 度量值使用一个匿名表来筛选模型,因此,它不能筛选数据模型的任何列。

下面是应用筛选器的正确方法(这里使用 CALCULATE 筛选器参数的完整语法是出于演示目的)。我们只需要一个条件就能筛选 Product[Color]:

Test :=
CALCULATE (
    [Sales Amount],
    FILTER ( ALL ( 'Product'[Color] ), 'Product'[Color] IN { "Red", "Blue" } )
)

数据沿袭的工作流

数据沿袭的工作流程是这样的:ALL 返回一个包含所有产品颜色的表,包含来自原始列的值,因此 DAX 知道每个值的含义。FILTER 扫描包含所有颜色的表,并检查每个颜色是否包含在由红色和蓝色组成的匿名表中。最终,FILTER 返回一个包含 Product[Color]值的表,因此 CALCULATE 知道筛选应用于 Product[Color]列。

你可以将数据沿袭想象为添加到每个列的特殊标记,目的是标识列在数据模型中的位置。

一般来说你不必专门考虑数据沿袭,因为 DAX 以一种自然和直观的方式处理这背后的复杂性。例如,当表中的值被分配给变量,那么此变量在后续整个 DAX 计值过程中都将具有该表的数据沿袭信息。

学习数据沿袭之所以重要,是因为我们经常需要根据不同的场景保持或更改数据沿袭。在某些场景中,保持数据沿袭非常重要,而在另外一些场景中,可能需要更改某些列的沿袭。

理解 TREATAS

将来自第一参数的列视为来自其他表的列,并继承它们的数据沿袭,对于每一列,TREATAS 剔除其在各自的输出列中不存在的值。

TREATAS ( <Expression>, <ColumnName>, [ <ColumnName>, [ … ] ] )

TREATAS 将<ColumnName>的数据沿袭分配给<Expression>中对应的列。你可以将结果作为变量在后续表达式中调用,因为 TREATAS 不是 CALCULATE 调节器。另外,它的第一参数必须是表表达式。

下面这个公式计算红色和蓝色产品的销售额,第一参数使用了匿名表:

Test :=
CALCULATE ( [Sales Amount], 
            TREATAS ( { "Red", "Blue" }, 'Product'[Color] ) 
)

TREATAS 返回一个继承 Product[Color]列沿袭的表,表中标记了第一参数列出的值。 因此,这个新版本的测试度量值只筛选红色和蓝色,如图所示。

TREATAS 更新了匿名表的沿袭,因此筛选器可以正常工作

多参数 TREATAS

你可以将 TREATAS 用于两列或多列的情况,第一参数中的列按顺序与后面的列一一对应。公式写法如下

[Filtered Measure] := 
CALCULATE (
    <target_measure>,
    TREATAS (
        SUMMARIZE (
            <lookup_table>
            <lookup_granularity_column_1>
            <lookup_granularity_column_2>
        ),
        <target_granularity_column_1>,
        <target_granularity_column_2> 
    )
)

注意事项

1. TREATAS 的第一参数必须是表表达式,TREATAS 的结果可以赋值给变量,因为 TREATAS 不是 CALCULATE 调节器

2. TREATAS 将第二参数的数据沿袭赋给表达式返回的列,使其可以筛选模型。虽然没加任何参数,但第二参数隐式使用了 ALL,以确保不被外层上下文影响。如果需要使外部筛选上下文可以筛选 TREATAS,可以配合 KEEPFILTERS 使用。

3. 如果第一参数中返回的值在列中不存在,将会被忽略。例如:

TREATAS({"Red"、"Green"、"Yellow"},DimProduct[Color])

公式在 DimProduct[Color]上设置一个筛选器,其中有三个值 Red、Green 和 Yellow。如果 DimProduct[Color]中不存在“黄色”,则有效筛选值为“红色”和“绿色”。

4. Excel 在 Excel 2016 的 1809 版本之后开始支持 TREATAS 函数,但智能感知可能无法识别,你需要完整的写出函数。

DAX 虚拟关系筛选方法总结

了解虚拟关系

虚拟关系是一种常见的 DAX 模式,虚拟的关系也可以将筛选上下文从一个表传输到另一个表,虚拟关系并不存在,但是可以模拟数据模型中物理(实体)关系的效果。以下几种情况需要用到虚拟关系

  • 当关系不存在时,
  • 当关系不是一对多而无法创建关系时
  • 当关系由两个或多个列定义时
  • 当存在循环依赖无法创建新关系时
虚拟关系与实体关系的区别是,实体关系是以物理方式建立并存在于模型中,模型视图中的实线关系和虚线关系都属于实体关系,而虚拟关系不可见,通过映射数据沿袭的方式生效。

有三种函数可以实现虚拟筛选,

本文隐藏内容查看价格为5G币,请先
单独购买的内容长期有效,不受时间限制(购买前先刷新当前页面)。加入VIP会员可享受全站权益,性价比更高。

总结

本文介绍了很多虚拟关系筛选的方式,但物理关系始终是你的首选,因为物理关系下的公式计算效率最高

  1. 首选物理关系
  2. 不能使用物理关系的情况下,使用 TREATAS 创建虚拟关系
  3. 当 TREATAS 不可用时,使用 INTERSECT 创建虚拟关系
  4. 当 TREATAS 和 INTERSECT 都不可用时,使用 FILTER+CONTAINS 创建虚拟关系
如果你使用 Power BI Desktop 和较新的 SSAS Tabular 版本,会发现某些情况下 TREATAS 的性能表现和物理关系接近甚至更好,这得益于新版本引擎的优化,但这种表现不具有普遍性,实际性能仍然需要以实测为准。另外,如果使用老版本的 DAX 引擎,比如 Power BI Report Server,你无法观察到优化带来的性能提升

 

30
说点什么

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

老师您好,我这有个模型,如果其中一个表物流码是唯一值,我能计算出异地扫码的数量countrows(filter(表1,表1[扫码地区]related表2[入库地区])),如果两个表物流码都有重复值(多对多)该怎么计算呢?

effc12ba0e910f83fadc51a4138c02b.png
成员
小本本

如果treats的第一个参数是多列的虚拟表, 并且这个虚拟表每一列都有treats第二参数以后的参数沿袭的模型列中没有的值, 那这个虚拟表的某一行第一列的值因为沿袭的模型列中没有被剔除,但是这一行其他列的值在沿袭的模型列中存在没有被剔除, 那这一行会如何处理, 整行被剔除? 还是只把这一行第一列的值设置成空, 保留这一行其他列的值?

treats测试 (小).png
游客
阿尔法

您好,下载的示例文件中无Product[Color]列,请问能再提供一般包含Product[Color]列的文档不?

成员
lyliuyouyang

你好,看了最后总结的那三个虚拟筛选的总结,我想到了一个案例,如图所示:先使用了selectcolumns创建了一个虚拟表,然后使用addcolunmns添加一个年份列。因为selectcolumns创建的虚拟表破坏了原始的标间关系,故需要用到虚拟筛选,table1使用了lookupvalue,因为addcolumns有行上下文,所以lookupvalue的第三参数不嵌套values就可以直接获取当前行值。但是换成table2的treatas就不行了,提示如图所示。请问是不是这种情况下,是不是不支持treatas?我试了一下intersect也是这样的提示,可能我的写法有问题?麻烦解惑,谢谢!

批注 2020-04-18 190138.jpg
批注 2020-04-18 185543.jpg
DAX 圣经

导读

初识 DAX

DAX 基础知识

DAX 原理

DAX 高级原理

基础函数类型

迭代函数

CALCULATE 函数

CALCULATE 调节器

基础表函数

条件判断函数

查找匹配函数

时间智能函数

统计类函数

投影函数

分组/连接函数

集合函数

其他函数