Power BI中的度量值、计算列和计算表

什么是计算列、什么是度量值

计算列是直接在现有的表上添加一个新列,

新建的计算列,和表中之前已经存在的列一样,可以作为表格的行、列,图表的轴以及切片器的字段等等,也可以使用计算列与其他表建立关系。

度量值,如果不放到上下文环境中,它就是一个孤立的公式,并没有视觉上的计算结果,因此,很多人会觉得度量值比较难以理解,尤其是Excel用习惯的人,都会倾向于使用计算列。

字段标识不同

如下图的字段面板

倒数第二个字段,前面有fx符号,代表的是计算列;而最下面一个,前面是个计算器的标识,表明[最后订单日期]是一个度量值。

怎么写计算列、怎么写度量值?

这个才是大家更关注的问题,也是平时容易出错的地方。下面以一个实例来介绍计算列与度量值的写法有什么不同。

以这个简化的订单表为例,如何计算出每个客户的最后下单时间?

计算列的写法

不少人也许直接这样写,

结果都是订单表中最后一个订单日期,显然与我们的期望不符,为什么会这样呢?

计算列的上下文就是当前行,但是MAX函数(包括SUM、MIN等聚合函数)并不能将行上下文转化为筛选上下文,也就是说当前行没有起到筛选作用,它就会返回整个表的最大订单日期。

关于上下文,不要理解的太复杂,完全可以按中文字面意思来理解,简单来说就是当前的计算环境,一般分为行上下文和筛选上下文,行上下文可以简单的理解为当前行,行上下文并不会必选产生筛选作用,只有筛选上下文才会产生筛选作用,筛选上下文有很多种形式,比如表格的当前行,矩阵的行和列、图表的座标轴、报表的切片器、筛选器等。

如何让当前行发生筛选作用呢?在MAX函数外围再套个CALCULATE函数就可以了,

这样返回的下单日期都不同了,但是仔细看就会发现,返回的日期和当前行的下单日期是一样的,并没有按照客户进行计算。

再强调一遍,计算列的上下文就是当前行,包括当前行的每一个值,在上表中,每一行的数据是唯一的,因此只能返回当前行的订单日期。

那么到底如何按照客户来计算,返回当前客户的最后下单日期呢?

解决这个问题的DAX写法有很多种,这里用个相对简洁的代码,

ALLEXCEPT函数的意思是,清除订单表其他列的筛选作用,只保留客户列的筛选,这样当前行的上下文,其他列的筛选作用清除了,只有客户发生筛选作用。

比如客户甲,有两笔订单,使用MAX计算出最大的订单日期,也就是甲的最后下单日期。

上面说了这么多计算列的写法,那么度量值该怎么写呢?

最后下单日期=MAX('订单表'[订单日期])

是不是简单到不敢相信,那么如何看到计算结果呢,最简便的方式就是直接用个表格或者矩阵展现结果,

再举个例子,依然是这个订单表,如何计算每个产品的最后卖出日期?

如果你理解了上面计算列的原理,这个问题是不是也很容易就出来了,

那么度量值又是如何写才能解决这个问题的呢?

其实度量值的写法可以完全不变,依然可以用上面的代码(MAX('订单表'[订单日期]),只要把表格的维度改为产品名称就可以了,

通过上面两个问题,你看出来计算列和度量值有哪里不同了吗?

在计算列中,其上下文是明确的,就是当前行,并且可以根据需要缩小为当前行的某一列;

而度量值,编写时并没有明确的上下文,度量值写好之后,可以放在任意的上下文环境中,执行不同的计算;

计算列写好代码,数据自动计算出来,并且不受外部筛选器的影响;

而度量值写好之后,并没有立即计算,只有放到上下文中时,才进行计算并返回结果。

所以利用DAX解决问题时,首先应想到上下文是什么,新建列时如何利用当前行的上下文?

而度量值虽然暂时没有上下文,但在建度量值之前,也首先应该想清楚,我需要构建怎样的上下文环境才能得到期望的结果,然后利用心中所想的上下文环境,来对应的编写度量值的DAX代码。

在PowerBI中,除了计算列和度量值,还有个地方可以用到DAX,就是使用DAX新建表,

使用建表的方式同时可以解决上面的问题,

其中VALUES('订单表'[客户]),返回客户的不重复列表,就是为了给后面的代码提供上下文,有了这个上下文,后面的代码与新建列的写法是一样的。

通过这三种使用DAX的环境,以及上面的几个例子,应该能发现,无论是度量值、计算列还是建新表,其DAX代码本质上并没有什么不同,不同的只是下上文而已。

计算列只能利用当前行上下文;新建表可以使用DAX构建上下文;’而度量值最灵活,先不管上下文,写好代码之后,给什么上下文,就执行什么运算,或者说需要什么计算,就给度量值提供什么上下文。

你以后再遇到问题打算用DAX实现,一定要先想清楚,是通过计算列、新表还是度量值来解决,然后再开始写对应的DAX。

计算列和度量值写法的不同点

关于计算列和度量值在写法上有一些不同,比如在计算列中使用列,可以直接使用,默认就是该列的当前行,比如返回当前订单日期的前一天,可以直接写:

而在度量值中使用列,必须在列上套一个聚合函数,否则不能自动转换为筛选上下文,计算订单日期前一天的度量值应该这样写:

订单日期前一天 = MAX('订单表'[订单日期])-1

什么时候使用新建列,什么时候使用度量值

一般来说,为了性能考虑,能用度量值解决的问题就尽量不用计算列(参考:高效使用Power BI的15条建议)。

只有当你需要利用新建的计算列生成切片器(度量值不能用于切片器),或者需要用这个字段与其他表建立关系时,才需要新建列。

另外当需要创建很复杂的字段时,尽量使用计算列,因为它需要时间来运算,提前运算完成,而不是在需要用的时候再进行计算(度量值是用的时候才计算),可以带来更流畅的体验。

总结

计算列和度量值在DAX代码的写法上并没有本质不同,形式上的不同只是由于上下文环境的区别引起的。

二者的本质不同在于其运算特点,是否根据上下文动态运算、以及计算时间上的不同,才是根本的差异。



《PowerBI商业数据分析》上市了

-精彩推荐-

PowerBI数据分析和可视化实战案例

Power BI商业数据分析模型:RFM客户价值分析

如何用PowerBI 打造高大上的财务报表分析报告?

采悟 from PowerBI星球

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章