DAX从入门到精通

DAX从入门到精通 4-4 学习filter,all和上下文交互

2019-07-08  本文已影响0人  PowerBI入门到实践

在之前的案例中,我们使用了filter来过滤一个表格。filter是非常常用的函数,当你想用来进一步限制上下文。
现在,设想一下,你要建立一个度量值来计算红色的产品数量。按我们现有的知识,函数很简单。

[NumOfRedProducts] :=
COUNTROWS (
FILTER (
Product,
Product[Color] = "Red"
))

这个函数可以正常工作,并且可以用于透视表。例如,我们可以把brand放到行中得到下面的结果:


image.png

在继续深入前,最好是停下来思考下,DAX是如何计算出这些结果的。brand是product表的一类。计算引擎对每个单元格计算NumOfRedProducts,每个单元格都是在上下文环境下计算的。所以,每个单元格显示的结果都是当前brand下的红色的产品的数量。之所以这样,是因为,当我们迭代产品表的时候,我们以及在上下文环境下,只能迭代品牌等于当前行的。再三的重复这个过程,是因为非常重要。
当我们在报表中设置一个切片器的时候,更能说明这个问题。下图中,我们建立了两个典型的透视表,使用的是color。左边的我们选择了red,值和之前的一样。而右边的透视表是空的,因为我们选择了绿色。


image.png
在右边的透视表,product表只有传递了绿色的产品,但是没有产品可以同时是绿色和红色。所以总是返回blank(),所以countrows()函数都结果是0
这个案例的重点在于,对于同一个函数,同时存在着来自于外部的筛选器(透视表表生成的,也受到切片器的影响)也存在着行上下文筛选器。两种筛选器同时工作,并共同决定了公式的计算结果。DAX使用筛选上下文来过滤product表,然后使用行上下文在进行迭代计算。

这个时候,你可能想定义另外一个公式,无论筛选器选择了什么,都显示红色产品的数量。因此,你希望可以忽略筛选器的选择,令公式总是返回红色的产品数。
要解决这个问题,使用all函数就可以了。all函数忽略了筛选上下文,总是返回表格的所有行。我们可以定义个新的度量值 NumOfAllRedProducts.

[NumOfAllRedProducts] :=
COUNTROWS (
FILTER (
ALL ( Product ),
Product[Color] = "Red"
))

现在,不再只是使用product,我们 使用了all(product),意思就是我们要忽略已经存在的筛选上下文,要迭代整个product表。整个计算结果不是我们预期的。


image.png

这里有几点非常有趣:
结果总是99,无论你选择什么品牌,结果都是99.
左边透视表的brand和右边表格的brand不一样。
我们来讨论下这两个话题。首先,99是数据库中所有red产品的数量。使用all函数,我们把所有的筛选器都移除了product表。也就是我们把color和brand的筛选器都清除了。这个不是我们希望的,但是以我们现有的知识,我们没有其他的选择来做到。all函数的影响力很大,但是它是一个要么全部使用,要么不使用的函数。如果使用,它移除了所有的筛选条件。没有移除部分筛选器的功能。我们这里想要的,就是我们希望只移除color筛选,保留其他的筛选条件。再下一章,我们会介绍解决这个问题的方式:使用calculate。
第二个问题就比较好理解:因为我们选择了green,我们就只能看到green产品的厂家,而不是所有产品的厂家。这样的结果就是,右边的透视表显示的是数据库中所有绿色产品厂家生产的所有红色的产品数。之所以会这样,是因为透视表的横轴,我们使用了manufactures,它会在原始的筛选上下文中计算,颜色是绿色。一旦横轴已经计算好了,那就开始计算值,也就是所有的产品99。
这个问题,我们不在这里解决。后面我们学习calculate的时候,会举例子来解决类似这样的场景。这里展示这个案例,是因为即使很很简单的表达式,因为公式中上下文的交互和互相影响,你会得到一些看起来很奇怪的结果。

上一篇下一篇

猜你喜欢

热点阅读