如何编写优化的 DAX 度量以按属性按两组聚合值
How to write an optimized DAX Measure to aggregate a value by two group by attributes
如果我们需要通过 DAX 中的两个属性聚合(Sum)一个值组怎么办。我用 Summarize 函数写了下面的度量,但是它很慢。
Reorder :=
SUMX (
SUMMARIZE (
TableA,
TableA[ProdID],
TableA[CustID],
"ReordersCount",
VAR VarInvoiceCount =
SUM ( TableA[InvoiceCount] )
RETURN
IF ( VarInvoiceCount > 0, VarInvoiceCount - 1, 0 )
),
[ReordersCount]
)
我还寻找了 SummarizeColumns,但当我应用其他属性切片器时它在报告中不起作用。可能是我遗漏了什么?
寻找优化的解决方案。非常感谢。
考虑以下方法:
首先,为发票总数创建一个度量:
Total Invoice Count = SUM(TableA[InvoiceCount])
其次,创建一个度量来计算首次发票的数量,这只是您 table:
中的一些独特的产品-客户组合
First Invoice Count =
COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
最后,想要的结果就是这两个措施的区别:
Reorder Count = [Total Invoice Count] - [First Invoice Count]
该公式将正确响应所有切片器和过滤器,并且应该非常快,因为没有嵌套迭代循环,例如 SUMX(SUMMARIZE()),没有上下文转换,也没有由以下原因引起的循环内的回调使用 IF 语句(这是一个高级主题)。
当然,您可以使用变量将所有内容放在一个度量中:
Reorder Count =
VAR Total_Invoice_Count = SUM(TableA[InvoiceCount])
VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
VAR Reorder_Count = Total_Invoice_Count - First_Invoice_Count
RETURN Reorder_Count
虽然我个人更喜欢分解度量,因为单个度量更容易理解和调试,并且它们可能有自己的用途。
上述方法非常有效,但它假定 TableA 仅包含有效订单。如果它还有取消、returns 等,可能有零或负的发票计数,那么您将不得不使用效率较低的方法,例如:
Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
VAR Reorder_Count = CALCULATE ( SUM ( TableA[Invoice] ) ) - 1
RETURN
IF ( Reorder_Count > 0, Reorder_Count, 0 )
)
或:
Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
MAX(CALCULATE ( SUM ( TableA[Invoice] ) ) - 1, 0) )
尽管如此,它们应该仍然比您的原始公式更快。
如果我们需要通过 DAX 中的两个属性聚合(Sum)一个值组怎么办。我用 Summarize 函数写了下面的度量,但是它很慢。
Reorder :=
SUMX (
SUMMARIZE (
TableA,
TableA[ProdID],
TableA[CustID],
"ReordersCount",
VAR VarInvoiceCount =
SUM ( TableA[InvoiceCount] )
RETURN
IF ( VarInvoiceCount > 0, VarInvoiceCount - 1, 0 )
),
[ReordersCount]
)
我还寻找了 SummarizeColumns,但当我应用其他属性切片器时它在报告中不起作用。可能是我遗漏了什么? 寻找优化的解决方案。非常感谢。
考虑以下方法:
首先,为发票总数创建一个度量:
Total Invoice Count = SUM(TableA[InvoiceCount])
其次,创建一个度量来计算首次发票的数量,这只是您 table:
中的一些独特的产品-客户组合First Invoice Count =
COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
最后,想要的结果就是这两个措施的区别:
Reorder Count = [Total Invoice Count] - [First Invoice Count]
该公式将正确响应所有切片器和过滤器,并且应该非常快,因为没有嵌套迭代循环,例如 SUMX(SUMMARIZE()),没有上下文转换,也没有由以下原因引起的循环内的回调使用 IF 语句(这是一个高级主题)。
当然,您可以使用变量将所有内容放在一个度量中:
Reorder Count =
VAR Total_Invoice_Count = SUM(TableA[InvoiceCount])
VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
VAR Reorder_Count = Total_Invoice_Count - First_Invoice_Count
RETURN Reorder_Count
虽然我个人更喜欢分解度量,因为单个度量更容易理解和调试,并且它们可能有自己的用途。
上述方法非常有效,但它假定 TableA 仅包含有效订单。如果它还有取消、returns 等,可能有零或负的发票计数,那么您将不得不使用效率较低的方法,例如:
Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
VAR Reorder_Count = CALCULATE ( SUM ( TableA[Invoice] ) ) - 1
RETURN
IF ( Reorder_Count > 0, Reorder_Count, 0 )
)
或:
Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
MAX(CALCULATE ( SUM ( TableA[Invoice] ) ) - 1, 0) )
尽管如此,它们应该仍然比您的原始公式更快。