带和不带 FILTER 的 DAX 计算函数

Posted

技术标签:

【中文标题】带和不带 FILTER 的 DAX 计算函数【英文标题】:DAX Calculate function with and without FILTER 【发布时间】:2018-11-03 11:39:21 【问题描述】:

CALCULATE 函数使用和不使用 FILTER 函数的结果有何不同。假设我们有这两个度量:

Measure1 = CALCULATE([X], 'FactTable'[Color]="Red")

Measure2 = CALCULATE([X], FILTER('FactTable', 'FactTable'[Color]="Red")

更新

有没有办法通过使用其他函数来修改Measure2,例如ALLALLSELECTED,使其返回与Measure1完全相同的结果>?

【问题讨论】:

你可以让[Measure2]返回同样的结果:CALCULATE([X], FILTER(ALL('FactTable'[Color]), 'FactTable'[Color]="Red") 您确定此度量会重现与 C 列中 Adam Luniewski 答案相同的结果吗?我的意思是过滤后的值将出现在任何日期的所有行中,而 D 列中没有任何空白? 是的,你的 measure1 只是我的 measure 的一种快捷语法。试试看! 【参考方案1】:

不仅结果,而且两种措施获得这些结果的方式也不相同。

我创建了两个类似于您的示例的度量来测试这个:

TestAvgNoFilter = CALCULATE([PrcAvg]; cal[ReadDate]=DATE(2018;05;23))
TestAvgFilter = CALCULATE([PrcAvg]; filter(cal; cal[ReadDate]=DATE(2018;05;23)))

当我只是将它们都放入数据透视表而不使用任何其他字段或切片器时,当然它们都会显示相同的结果:

但是:

    使用FILTER 对性能有显着影响,从查询计划和存储引擎与公式引擎的利用率中可以清楚地看出这一点。它创建了额外的临时表,它需要与来自报告/数据透视表本身(行、列、切片器)的现有过滤器“交互”。您不会注意到单个单元格中的简单平均值,但如果您的 [x] 度量本身很复杂并且有许多“初始”过滤器,则计算时间的差异可能会很大。

    FILTER 保留并与初始过滤器上下文进行迭代,而直接在 CALCULATE 中使用的过滤器表达式会忽略它。看看当我将 ReadDate 添加到数据透视表时会发生什么:

这正是没有 FILTER 的度量更快的原因:它不关心列中的日期 - 它已经计算了一个“真实”值,而具有 FILTER 的度量根据每个初始过滤器评估自己排。

两列中的结果都可以被认为是正确的 - 这实际上完全取决于解释以及您如何命名度量;)。

作为一般规则,我建议您在不需要时不要使用FILTER。在真正需要的时候省电。

【讨论】:

您在第一点中已经说过它对性能有重大影响,但您没有明确表示支持 W 或 WO FILTER 功能。请告诉带过滤器和不带过滤器哪个更快。我喜欢你第 2 点的例子。谢谢! @PrzemyslawRemin 你读完他的回答了吗?他肯定会推荐哪个更快。 是的,我现在看到了。谢谢。我不得不省略它。【参考方案2】:

这里的区别在于CALCULATE 允许使用简单的过滤器来替换现有的过滤器上下文。在您的示例中,CALCULATE 将使用现有过滤器上下文计算度量 [X],但它会删除 FactTable[Color] 的任何现有过滤器上下文并将其替换为 FactTable[Color] = Red.

FILTER 函数是一个迭代器,这意味着它一次遍历表(作为其第一个参数传入)一行,并计算每一行的表达式(第二个参数)。当您在CALCULATE 中有一个FILTER 函数时,它会将现有的过滤器上下文与FILTER 的结果结合起来(而不是像简单的过滤器参数那样替换它)。

一般来说,只要有选择,您就希望使用简单的过滤器,因为计算效率会更高。但是,FILTER 函数允许您执行更复杂的过滤,因此在简单过滤器不够用的情况下它仍然非常有用。


延伸阅读:FILTER() – When, Why, & How to Use It

【讨论】:

【参考方案3】:

DAX 生成的自动 FILTER 函数代替逻辑表达式的 DAX 语法要求您在过滤器表达式中表达单个列。让我们举个例子 -

Measure1 = CALCULATE([X], 'FactTable'[Color]="Red")

上面的语法在下面的语法中进行了内部转换,您可以用一种明确的方式编写它,从您的 DAX 度量中获取相同的行为。

Measure1 = CALCULATE([X], FILTER(ALL('FactTable'[Color]), 'FactTable'[Color]="Red"))

因此,如果您在 Measure2 值中使用最后一个函数,它将获取相同的结果。

For further reference you can visit this link.

【讨论】:

如果这个答案解决了你的问题,你能接受这个答案吗? 不,我不会将您的帖子标记为已接受的答案。 Adam Luniewski 对我最初的问题进行了最广泛的解释。您的帖子是对稍后提出的赏金问题的回复,我为此授予您赏金。 所以你能接受他的回答吗,因为在你这样做之前,这个问题将保持开放。【参考方案4】:

您创建的度量将具有相同的输出,因为您只传递一个值以过滤为颜色“红色”。

但是,如果您想传递值范围(如日期范围)进行过滤,Measure1 将无法工作,因为它只传递单个值进行过滤,因此无法做到这一点。

Measure2 中,您可以使用特定表和列中的 FILTER 函数传递特定值的范围以获得所需的输出。

Measure2 = CALCULATE([X], FILTER('FactTable', 'FactTable'[Color])

您可以使用 FILTER 减少您正在使用的表中的行数,并在计算中仅使用特定数据。

您可以在此处找到有关 FILTER 功能的更多详细信息以及其工作原理的示例 -

https://msdn.microsoft.com/en-us/query-bi/dax/filter-function-dax

【讨论】:

以上是关于带和不带 FILTER 的 DAX 计算函数的主要内容,如果未能解决你的问题,请参考以下文章

带和不带引号和括号的 setTimeout 之间的区别

头文件带和不带.h的区别

Kotlin 只读属性,带和不带 getter

带和不带 () 的条件运算符

带和不带的 SQL 查询

在mysql中执行带和不带索引的查询