DAX从入门到精通 2-2-2 度量值
度量值
在模型中还有另外一种定义计算的方式,当你不想对每行都计算,而是想获取行的汇总值时候。我们称为度量值。
例如:你可以定义GrossMargin列,来计算sale表的毛利润
Sales[GrossMargin] = Sales[SalesAmount] – Sales[TotalProductCost]
但是如果你想计算毛利润占销售额的比率。你可能会建立下面的计算列:
Sales[GrossMarginPct] = Sales[GrossMargin] / Sales[SalesAmount]
这个公式在行级别是正确的。
image.png
但是,你算一个汇总值的 比例,你不能依靠计算列。这时候,应该计算gross margin的汇总除以销售额的汇总。
因此在这个例子中,你需要计算的比例,你不能依靠计算列的汇总,换句话说就是,你要计算汇总值的比例,而不是比率的汇总值。
正确的写法是这样:
Sales[GrossMarginPct] := SUM ( Sales[GrossMargin] ) / SUM(Sales[SalesAmount] )
但是,我们上面说过,你不能直接使用计算列,如果你要使用汇总值计算而不是基于行,你需要使用度量值。你可能注意到我们使用了 := 来定义度量值,而不是 =。 这个是我们贯穿这本书的标准写法,可以更好的在代码中区别计算列和度量值。
计算列和度量值都是使用DAX表达式。他们的区别就是使用的计算内容不同。度量值是计算透视表的单元格或者DAX代码的内容,计算列是以表中当前行计算。度量值的计算单元格是根据用户选择的或者dax语句选择的,所以当你使用SUM(Sales[SalesAmount])作为度量值的时候,你的聚集条件就是当前选择的单元格条件,而但你把Sales[SalesAmount]作为计算列的时候,就是根据表的当前行计算。
度量值需要定义在某个表里面,这个是DAX语言所要求的。但是度量值又不是真正的属于某个表,也就是,你可以在不同表之间任意移动度量值,而度量值的功能还是一样的。
计算列和度量值的区别
计算列和度量值看起来虽然很类似,但是它们之间有着非常大的区别。计算列的计算是在数据模型刷新的时候,并且使用表格当前行的数据作为上下文。计算列的不会随着用户对透视表的操作而改变。而度量值,是对聚合数据进行操作,使用的是透视表中的上下文。举个例子,在透视表中,使用表格的行列进行筛选,数据源表格数据通过这些筛选条件进行聚合和计算。换句话说,就是度量值使用用户操作的上下文进行的筛选聚合,因此,度量值默认情况下,不能直接计算某个特定的行。在后面的章节,我们会详细的介绍。
何时使用计算列,何时使用度量值
目前为止,您已经明白了计算列和度量值之间的区别,你可能会有疑问,该何时使用度量值,何时使用计算列。有时,二者可以互相替代,但是大多数情况下,要根据计算的需要来决定。
当你有如下需求的时候,可以使用计算列:
- 需要把计算的结果用于筛选器,或者需要在透视表的行或者列使用(注意,不是值区域),或者在DAX函数中作为筛选条件。
- 定义一个值,它的计算严格限制于当前行。例如Price * Quantity,它不能通过两列的平均值或者总和的计算后得出。
- 对值或者数字分类(例如,你需要一个度量值,它对一些值进行分类,一个年龄范围内的客户,例如0-18,18-25岁等)
但是,当你需要吧计算结果展示在客户选择条件下的值的时候,就需要使用度量值了。
- 当计算透视表的百分数占比的时候。
- 当计算某一个产品相对于所有产品,并且同时需要按年度和地区筛选。这样的情景的时候。
有些计算,可以使用计算列或者度量值,或者使用不同的DAX表达式都是正确。例如,你可以在计算列定义GrossMargin
Sales[GrossMargin] = Sales[SalesAmount] - Sales[TotalProductCost]
同时,这个也可以这样定义,使用度量值。
[GrossMargin] := SUM ( Sales[SalesAmount] ) – SUM (Sales[TotalProductCost] )
这里,我建议使用度量值,因为在计算结果的时候,度量值不会消耗内存和磁盘空间,但是这只是在非常大数据量的情况下,区别才会特别明显。如果数据量不大,两者都是合适的选择。