原文:Best practices using SUMMARIZE and ADDCOLUMNS
在实践中,可以用SUMMARIZE添加分组列,而用ADDCOLUMNS添加计算列。
ADDCOLUMNS(
SUMMARIZE( <table>, <group by column>,... ),
<column_name>, CALCULATE( <expression> ),...
)
CALCULATE 并非始终是必需的,但只要 <expression> 包含聚合函数,就应该加上CALCULATE函数。原因是 ADDCOLUMNS 在行上下文中运行,不会自动传播到筛选上下文中,而 SUMMARIZE 中的相同 <expression> ,则会在与分组列中的值相对应的筛选上下文中执行。
举个例子:按照Country统计Store表中的数据行。
EVALUATE
ADDCOLUMNS (
SUMMARIZE (
Store,
Store[Country]
),
"Stores", COUNTROWS ( Store )
)
EVALUATE
ADDCOLUMNS (
SUMMARIZE (
Store,
Store[Country]
),
"Stores", CALCULATE ( COUNTROWS ( Store ) )
)
SUMMARIZE 与 ADDCOLUMNS 之间的过滤器上下文有所不同。
举个例子:当对未包含在分组列中的列应用过滤器,并且使用来自相关表的数据计算扩展列表达式时,SUMMARIZE 与 ADDCOLUMNS 之间的过滤器上下文将有所不同。下面的两个DAX的结果不同:
EVALUATE
SUMMARIZE (
GENERATE (
'Product',
TOPN (
2,
Customer,
[Sales Amount]
)
),
Product[Category],
Customer[Country],
"Margin", [Margin]
)
ORDER BY [Margin] DESC
EVALUATE
ADDCOLUMNS (
SUMMARIZE (
GENERATE (
'Product',
TOPN (
2,
Customer,
[Sales Amount]
)
),
Product[Category],
Customer[Country]
),
"Margin", [Margin]
)
ORDER BY [Margin] DESC
很明显,结果不同,因为利润率高于初始结果。这是因为此查询在仅过滤Product[Category]和Customer[Country]的筛选上下文中计算利润率度量,忽略了 SUMMARIZE 的表参数中使用的前 2 个客户的筛选器,其中 GENERATED 的结果包括产品和客户的所有列,但仅针对每个国家/地区的前 2 个客户。SUMMARIZE 中的利润率计算仅考虑这些客户,因为 SUMMARIZE 仅使用按 TOPN 筛选的客户。
如果将 SUMMARIZE 包装到 ADDCOLUMNS 中,则在 ADDCOLUMNS 中创建的扩展列将在由 Product[Category] 和 Customer[Country] 定义的筛选上下文中工作,考虑的销售额比初始查询最初使用的销售额多得多。因此,为了使用 ADDCOLUMNS 生成等效结果,有必要在以下利润度量评估中使用由 GENERATE 获得的相同过滤器。我们可以通过将 GENERATED 的结果存储在我们在 SUMMARIZE 中引用的 ProductsCustomers 变量中来实现这一点,并将其作为过滤器参数传递给 CALCULATE 以评估 ADDCOLUMNS 中的利润度量。使用 KEEPFILTERS 对于保留上下文转换的结果以及在 ProductsCustomers 中存储的过滤器中按 Product[Category] 和 Customer[Country] 进行过滤至关重要。
这是使用 ADDCOLUMNS 生成扩展列的等效 DAX 查询:
EVALUATE
VAR ProductsCustomers =
GENERATE (
'Product',
TOPN (
2,
Customer,
[Sales Amount]
)
)
RETURN
ADDCOLUMNS (
SUMMARIZE (
ProductsCustomers,
Product[Category],
Customer[Country]
),
"Margin",
CALCULATE (
[Margin],
KEEPFILTERS ( ProductsCustomers )
)
)
ORDER BY [Margin] DESC
结论是,如果 SUMMARIZE 中使用的表具有特定过滤器,并且扩展列表达式使用的列不存在于输出结果中,那么就不应将 SUMMARIZE 表达式中的扩展列移出到 ADDCOLUMNS。即使您可以创建等效的 ADDCOLUMNS 查询,结果也会更复杂,并且此重构不会带来任何性能优势。