为什么我的计算列中的 DAX 公式在一个实例中而不是在另一个实例中使用传播来过滤?
Why does the DAX formula in my calculated column use propagation to filter in one instance and not in another?
假设我有几个 tables:
fTransactions
Index ProdID RepID Revenue
1 1 1 10
2 1 1 20
3 2 2 30
4 2 2 10
d销售代表
RepID RepName CC1 CCC2
1 joe 40 70
2 sue 30 70
3 bob 70
CC1 包含一个计算列:
CALCULATE(SUM(fTransactions[Revenue]))
据我了解,它正在获取行上下文并更改为筛选上下文以将 fTransaction table 筛选为 RepID 并求和。根据关于该主题的 sqlbi 篇文章说得通:
"because the filter context containing the current product is automatically propagated to sales due to the relationship between the two tables"
CC2 包含一个计算列:
SUMX(fTransactions, CALCULATE(SUM(fTransactions[Revenue]))
但是,这个例子在所有列中放置了相同的值,并且似乎不像另一个例子那样传播 RepID。同一篇 sqlbi 文章提到对整个 fTransactions 行进行了筛选。 我的问题是为什么它在这里而不是另一个例子这样做,RepID 的传播发生了什么?
"CALCULATE places a filter on all the columns of the table to identify a single row, not on its row number"
在循环中创建一个计算列:幂轴逐行计算结果。 CALCULATE 将每一行转换为过滤器上下文(上下文转换)。
然而,在第二个公式中,您有 2 个循环,而不是一个:
首先,它循环 dSalesReps table(因为这是您创建列的位置);
其次,它循环 fTransactions table,因为您使用的是迭代器 SUMX 函数。
CALCULATE 函数仅在第二个循环中使用,强制 fTransactions table 中每一行的上下文转换。但是没有 CALCULATE 可以强制 dSalesReps 中的行进行上下文转换。因此,销售代表没有过滤。
解决问题很简单:只需将第二个公式包装在 CALCULATE 中即可。更好的是,删除第二个 CALCULATE - 它不是必需的并且会使公式变慢:
CCC2 =
CALCULATE(
SUMX(fTransactions, SUM(fTransactions[Revenue]))
)
这个公式和第一个公式本质上是一样的(后台第一个公式翻译成第二个,SUM函数只是SUMX的语法糖)。
您也可以将公式写成:
CC2 = SUMX( RELATEDTABLE( fTransactions ), fTransactions[Revenue] )
或
CC2 = SUMX( CALCULATETABLE( fTransactions ), fTransactions[Revenue] )
关键是作为 SUMX 的第一个参数的 fTransactions 需要为每个 SalesRep 过滤(即在当前行)。如果没有过滤器,那么您只是为每个 SalesRep 迭代整个 fTransactions table。 SUMX 需要以某种方式知道您只需要您尝试计算其收入的销售代表的 fTransactions。
假设我有几个 tables:
fTransactions
Index ProdID RepID Revenue
1 1 1 10
2 1 1 20
3 2 2 30
4 2 2 10
d销售代表
RepID RepName CC1 CCC2
1 joe 40 70
2 sue 30 70
3 bob 70
CC1 包含一个计算列:
CALCULATE(SUM(fTransactions[Revenue]))
据我了解,它正在获取行上下文并更改为筛选上下文以将 fTransaction table 筛选为 RepID 并求和。根据关于该主题的 sqlbi 篇文章说得通:
"because the filter context containing the current product is automatically propagated to sales due to the relationship between the two tables"
CC2 包含一个计算列:
SUMX(fTransactions, CALCULATE(SUM(fTransactions[Revenue]))
但是,这个例子在所有列中放置了相同的值,并且似乎不像另一个例子那样传播 RepID。同一篇 sqlbi 文章提到对整个 fTransactions 行进行了筛选。 我的问题是为什么它在这里而不是另一个例子这样做,RepID 的传播发生了什么?
"CALCULATE places a filter on all the columns of the table to identify a single row, not on its row number"
在循环中创建一个计算列:幂轴逐行计算结果。 CALCULATE 将每一行转换为过滤器上下文(上下文转换)。
然而,在第二个公式中,您有 2 个循环,而不是一个: 首先,它循环 dSalesReps table(因为这是您创建列的位置); 其次,它循环 fTransactions table,因为您使用的是迭代器 SUMX 函数。
CALCULATE 函数仅在第二个循环中使用,强制 fTransactions table 中每一行的上下文转换。但是没有 CALCULATE 可以强制 dSalesReps 中的行进行上下文转换。因此,销售代表没有过滤。
解决问题很简单:只需将第二个公式包装在 CALCULATE 中即可。更好的是,删除第二个 CALCULATE - 它不是必需的并且会使公式变慢:
CCC2 =
CALCULATE(
SUMX(fTransactions, SUM(fTransactions[Revenue]))
)
这个公式和第一个公式本质上是一样的(后台第一个公式翻译成第二个,SUM函数只是SUMX的语法糖)。
您也可以将公式写成:
CC2 = SUMX( RELATEDTABLE( fTransactions ), fTransactions[Revenue] )
或
CC2 = SUMX( CALCULATETABLE( fTransactions ), fTransactions[Revenue] )
关键是作为 SUMX 的第一个参数的 fTransactions 需要为每个 SalesRep 过滤(即在当前行)。如果没有过滤器,那么您只是为每个 SalesRep 迭代整个 fTransactions table。 SUMX 需要以某种方式知道您只需要您尝试计算其收入的销售代表的 fTransactions。