这篇文章以在新建列内引用度量值说明三件事:
- 列和度量值引用书写规范的重要性:总是在列引用的前面加表名, 而在度量值引用的前面忽略表名. 以快速识别列或度量值的引用。
- 总是在CALCULATE函数内解读一个度量值的引用:特别注意行上下文内引用度量值时, 将触发上下文转变 - 引擎自动将当前迭代行中的所有列以布尔表达式的形式增加进CALCUALTE 的筛选参数。
- 不正确的假设将导致错误的结果。
首先熟悉下模型:
第二步, 新建度量值Sales Amount, 在Sales表新建列WrongSalesAmount, 在Product表新建列ProductSales, WrongProductSales, ProductSalesRatio. 代码分别如下:
度量值SalesAmount
Sales Amount =
SUMX ( Sales, Sales[Quantity] * Sales[Net Price] )
Sales表内的新建一列WrongSalesAmount
WrongSalesAmount = [Sales Amount]
Product表的新建列
新建列ProductSales
ProductSales = [Sales Amount]
新建列ProductSales
WrongProductSales =
SUMX('Sales',Sales[Net Price]*Sales[Quantity])
新建列ProductSalesRatio
ProductSalesRatio =
VAR TotalSales = [Sales Amount]
VAR ProductSales =
CALCULATE ( [Sales Amount] )
RETURN
DIVIDE ( ProductSales, TotalSales )
第三步, 建立一个矩阵表, Brand 放在行上, 度量值Sales Amount 和计算列WrongSalesAmount放在值上。我们发现行"Fabrikam"和"总计"的计算结果不一样.
因为:
- Sales 表中没有具有唯一不重复值的一列, 所以Sales可能有重复的行。
- 度量值的引用, 引擎默认用CALCULATE 函数套着定义度量值的表达式, 因为计算列为每行自动创建了一个行上下文, 所以将触发上下文转变。 所以对于WrongSalesAmount 表达式, 正确的解读方式是:
WrongSalesAmount =
CALCULATE ( SUMX ( Sales, Sales[Quantity] * Sales[Net Price] ) )
而且Sales 表可能有重复的行, 所以当引擎将有重复行的行增加到CALCULATE函数的筛选参数内的时候, 将不仅仅筛选一 行, 而是筛选了所有的重复行, 然后在此数据集合下计算WrongSalesAmount. 所以我们看到WrongSalesAmount>Sales Amount
第四步, 我们在Product表看下新建三列的值发现:
- WrongProductSales 值在每一行都是一样的
- ProductSales 值在每一行不同
- PorductSalesRatio是在我们意识到计算列内引用度量值引擎自动增加CALCULATE将触发上下文转变情况下, 假设了使用变量储存TotalSales,ProductSales值然后计算ProductSalesRatio. 但是发现只要ProductSales 有值的行结果都是1.
因为:
1. 计算列WrongProductSales实际在计算所有产品的Sales Amount, 所以每一行都是结果相同
WrongProductSales =
SUMX('Sales',Sales[Net Price]*Sales[Quantity])
2. 计算列ProductSales引用了度量值Sales Amount, 所以正确的解读方式是在定义Sales Amount 度量值的表达式外面增加一个CALCULATE 函数, 因为计算列为每行自动创建了一个行上下文, 所以将触发上下文转变; 而且Porduct表位于关系的一端, 所以有一列ProductKey在每一行都是唯一不重复的值. 所以虽然引擎把Porudct 表的每一行的值增加到了CALCUALTE的筛选参数里面, 但是仅仅筛选的Product 的每一行. 也就是计算了每个Product的Sales Amount
ProductSales =
CALCULATE ( SUMX ( Sales, Sales[Quantity] * Sales[Net Price] ) )
3. 计算列ProductSalesRatio: 虽然我们假设了使用变量储存TotalSales,ProductSales值然后避免上下文的转变, 然后计算ProductSalesRatio. 但是潜意识欺骗了我们, 因为我们再次忽略了每个度量值的引用都有一个隐性的CALCUALTE函数套着它。所以对ProductSalesRatio的正确解读是如图所示, 所以TotalSales和ProductSales都是在计算每个Product的Sales Amount。