使用迭代器函数

已完成

迭代程序函数计算表中每行的表达式。 它们使您能够灵活地控制模型汇总数据的方式。

单列汇总函数(例如 SUMCOUNTMINMAX)都有包含“X”前缀的等效迭代程序函数(例如 SUMXCOUNTXMINXMAXX)。 此外,还存在专用迭代程序函数,用于筛选、排名和随时间推移的半加法计算。

每个迭代程序函数都需要一个表和一个表达式。 表可以是模型表或返回表的任何表达式。 表达式必须为每行返回一个值。

单列汇总函数(例如 SUM)充当速记函数。 Power BI 在内部将 SUM 转换为 SUMX。 例如,以下两个度量值返回相同的结果并具有相同的性能:

Revenue = SUM(Sales[Sales Amount])
Revenue =
SUMX(
    Sales,
    Sales[Sales Amount]
)

迭代程序函数使用行上下文计算表中每行的表达式,这意味着它们一次处理一行以计算最终结果。 然后,在筛选器上下文中计算该表。 例如,如果报表视觉对象按会计年度 FY2020 进行筛选,则 Sales 表仅包含该年度的销售行。

重要提示

使用包含大型表和复杂表达式的迭代程序函数可能会降低性能。 SEARCHLOOKUPVALUE 等函数可能很昂贵。 如果可能,请使用 RELATED 以获得更好的性能。

用于复杂汇总的迭代程序函数

迭代程序函数支持聚合多个列。 例如,收入度量值可以将每行的订单数量、单价和折扣系数相乘,然后将结果相加。

Revenue =
SUMX(
    Sales,
    Sales[Order Quantity] * Sales[Unit Price] * (1 - Sales[Unit Price Discount Pct])
)

迭代程序函数还可以引用相关表。 折扣度量值可以使用 RELATED 函数访问“product”表中的标价。

Discount =
SUMX(
    Sales,
    Sales[Order Quantity]
    * (
        RELATED('Product'[List Price]) - Sales[Unit Price]
    )
)

下图显示包含“Month”、“Revenue”和“Discount”列的表视觉对象。 “Revenue”和“Discount”是之前创建的度量值。

屏幕截图显示包含三列的表视觉对象:Month、Revenue 和 Discount。

用于更高粒度汇总的迭代程序函数

迭代程序函数还可以在不同的详细信息级别(粒度)汇总数据。 例如,您可能需要在行项级别或销售订单级别计算平均值。

在本示例中,Sales 表中针对销售订单中的每个行项占据一行。 每行都包含销售订单编号、产品、售出数量、单价和折扣等详细信息。 多行可以具有相同的销售订单编号,表示同一订单中的不同物料。

若要计算每个订单行(行项)的平均收入,您可以使用 AVERAGEX 函数迭代浏览 Sales 表中的每一行。 该公式将计算每个行项的收入,然后在当前筛选器上下文中对所有行项求平均结果:

Revenue Avg Order Line =
AVERAGEX(
    Sales,
    Sales[Order Quantity] * Sales[Unit Price] * (1 - Sales[Unit Price Discount Pct])
)

屏幕截图显示包含四列的表视觉对象:Month、Revenue、Discount 和 Revenue Avg。

如果要计算每个销售订单(而不是每个行项)的平均收入,您可以先使用 VALUES 函数获取唯一销售订单编号的列表。 然后,AVERAGEX 迭代浏览每个销售订单并计算每个订单的总收入的平均值:

Revenue Avg Order =
AVERAGEX(
    VALUES('Sales Order'[Sales Order]),
    [Revenue]
)

VALUES 函数根据当前筛选器上下文返回唯一销售订单,因此 AVERAGEX 将迭代浏览每个月的每个销售订单。

屏幕截图显示一个包含五列的表视觉对象:Month、Revenue、Discount、Revenue Avg Order Line 和 Revenue Avg Order。

使用迭代程序函数进行排名

RANKX 函数通过迭代浏览表并计算每行的表达式来计算排名。

顺序方向可以是升序,也可以是降序。 对收入进行排名通常使用降序顺序,因此最高值排在第一位。 对投诉之类的内容进行排名可能采用升序顺序,因此最低值排在第一位。 默认情况下,RANKX 使用降序顺序并跳过并列的排名。

例如,产品数量排名度量值可以使用 RANKXALL 函数以按数量对产品进行排名:

Product Quantity Rank =
RANKX(
    ALL('Product'[Product]),
    [Quantity]
)

ALL 函数删除筛选器,因此 RANKX 对所有产品进行排名。 在下图中,两个产品并列第十位,因此下一个产品排名第十二位,跳过排名 11。

屏幕截图显示具有两个产品并列的表视觉对象,如前所述。

您还可以使用密集排名,它在并列后分配下一个排名,而不会跳过数字。 若要使用密集排名,度量值可以包括 DENSE 参数:

Product Quantity Rank =
RANKX(
    ALL('Product'[Product]),
    [Quantity],
    ,
    ,
    DENSE
)

现在,在两个产品并列第十位之后,下一个产品排名第十一位,并且编号继续按顺序排列,不会跳过排名 11。

屏幕截图显示使用 DENSE 排名描述的表。

在此视觉对象中,Product Quantity Rank 度量值的总行显示 1,因为所有产品的总计也会进行排名,并且只有一个值。

屏幕截图显示“Product Quantity Rank”总计为 1。

为了避免对总计进行排名,度量值可以使用 HASONEVALUE 函数返回 BLANK,除非筛选了单个产品:

Product Quantity Rank =
IF(
    HASONEVALUE('Product'[Product]),
    RANKX(
        ALL('Product'[Product]),
        [Quantity],
        ,
        ,
        DENSE
    )
)

现在,Product Quantity Rank 的总计为空。

屏幕截图显示“Product Quantity Rank”总计为 BLANK。

HASONEVALUE 函数检查产品列在筛选器上下文中是否具有单个值。 这适用于每个产品组,但不适用于表示所有产品的总计。

迭代程序函数提供强大的方法来汇总、聚合 Power BI 模型中的数据并对其进行排名。 它们支持复杂的计算,并使您可以控制报表中的详细信息级别。