关于计算列和度量,你要知道的这些事儿!| PBI实战经验

- 1 -

先说一下经常被问到的几个问题。

问-1:需要计算列时,是在PP里计算列好, 还是PQ里添加自定义列好?

答:这个要看实际情况,我一般建议优先考虑在PQ里添加列,因为PQ里添加的自定义列,在PP里能用,而在PP里添加的计算列,在PQ里不能用。

但是,如果说,这个计算列,在PP里因为有表间的关系实现起来很方便且效率又高,而且又没有必要在PQ里的其它步骤或查询里引用,那在PP里实现可能就更好。

问-2:计算列的作用是不是主要用于关系列或切片器?

答:对的,但有时候为了计算方便,也加计算列,甚至,偶尔也可能会用来实现计算效率的提升(可参考圣经19-20章关于计算列的高级内容)。

问-3:同样添加列, 同一表中PP会比PQ要快吗?比如,金额 = 数量*单价

答:单纯从计算的角度来说,这种简单的计算应该没有什么大的效率差异。

问-4:行数不受影响吗?10W行,执行(A-B)*C 在PQ里建也是纯粹为了PP中分析,哪一种方式好?

答:这个你自己看需要用就是了。如果非必要,其实更建议直接用度量,而不是计算列。这种计算的结果,通常每行的结果数都不一样(即所谓的大基列),这样PP的引擎(Vertipaq)对这个列基本没有压缩,存储和内存开销会很大。

- 2 -

关于计算列和度量怎么选?可参考圣经以下总结:

当你想要执行以下操作时,你必须定义一个计算列:

  • 需要将计算结果置于 Excel 切片器;透视表行区域、列区域(而不是值区域);作为 DAX 查询的筛选条件。
  • 定义严格绑定到当前行的表达式。(例如,计算“价格* 数量”时不能对两列求和或求平均后再相乘)
  • 对文本或数值做分类时。(例如,度量值的范围,客户的年龄范围:比如 0-18,18-25 等等)。

然而,当你想在由用户设定筛选条件的数据透视表值区域中看到计算结果时,你必须定义一个度量值,例如:

  • 基于透视表的选择计算利润率百分比。
  • 存在年份和地区筛选器的情况下,计算一个产品占所有产品的比率。

你可以使用计算列和度量值来表示同一计算,即使在这种情况下需要使用不同的 DAX 表达式。例如,你可以将 GrossMargin 定义为一个计算列:

代码语言:javascript
复制
Sales[GrossMargin] = Sales[SalesAmount] - Sales[TotalProductCost]

也可以定义成度量值

代码语言:javascript
复制
GrossMargin:= SUM ( Sales[SalesAmount] ) – SUM( Sales[TotalProductCost])

在这种情况下,建议你使用度量值,因为其在查询时进行计算,这种方式对模型文件的大小几乎不会有任何影响,这在大型数据集中非常重要

- 3 -

最后总结一下:

如果模型本身并不大,那按照自己熟悉的方式构建计算列(包括PQ自定义列或PP计算列)或度量就可以了,不必过于纠结。

而对于数据量很大的情况,则需要根据具体情况进行专门的处理,可能有些可参考的基本原则和特定情境下的案例,比如:

  • 尽可能在数据源头规范数据,避免大量的数据清洗过程;
  • 尽可能避免内存的占用,如尽可能用度量,而不是计算列;
  • 尽可能降低算法的复杂度,如能用函数直接出结果,就不要用迭代;
  • 尽可能使用引擎内置的函数或功能,而避免过多的自定义函数;
  • ……

但是,说实话,这并没有太固定的处理方式,在具体的场景下,可能需要通过对比不同的方式,测试它们的效率,才能知道到底哪一种方法更适合。