其他时间智能计算

已完成

存在与返回单个日期相关的其他 DAX 时间智能函数。 在本单元中,您将通过在两个不同的应用场景中应用这些函数来了解它们。

FIRSTDATELASTDATE 函数返回当前筛选器上下文中指定日期列的第一个日期和最后一个日期。

计算新匹配项

时间智能函数的另一个用途是对新匹配项进行计数。 以下示例演示如何计算一个时间段内的新客户数。 新客户在其第一次购买的时间段内进行计数。

首先,将以下度量值添加到 Sales 表,用于对开始使用迄今 (LTD) 的不同客户数进行计数。 “开始使用迄今”是指筛选器上下文中从开始时间直到最后一个日期。 使用千位分隔符将度量值的格式设置为整数。

Customers LTD =
VAR CustomersLTD =
    CALCULATE(
        DISTINCTCOUNT(Sales[CustomerKey]),
        DATESBETWEEN(
            'Date'[Date],
            BLANK(),
            MAX('Date'[Date])
        ),
        'Sales Order'[Channel] = "Internet"
    )
RETURN
    CustomersLTD

Customers LTD 度量值添加到矩阵视觉对象。 请注意,它将生成开始使用迄今直到每月结束的不同客户的结果。

屏幕截图显示一个矩阵视觉对象,其中按“Year”和“Month”以及“Revenue”、“Revenue YTD”、“Revenue YoY %”和“Customers LTD”对行进行分组。

DATESBETWEEN 函数返回包含日期列的表,该日期列以给定开始日期开始,并一直持续到给定结束日期。 当开始日期为 BLANK 时,它将使用日期列中的第一个日期。 (相反,当结束日期为 BLANK 时,它将使用日期列中的最后一个日期。)在这种情况下,结束日期由 MAX 函数确定,该函数返回筛选器上下文中的最后一个日期。 因此,如果 2017 年 8 月这一月份在筛选器上下文中,则 MAX 函数将返回 2017 年 8 月 31 日,而 DATESBETWEEN 函数将返回一直到 2017 年 8 月 31 日的所有日期。

接下来,您将修改该度量值,方法是将其重命名为 New Customers,并添加第二个变量来存储筛选器上下文中时间段之前 的不同客户计数。 RETURN 子句现在从 LTD 客户中减去此值以生成结果,这是该时间段内的新客户数。

New Customers =
VAR CustomersLTD =
    CALCULATE(
        DISTINCTCOUNT(Sales[CustomerKey]),
        DATESBETWEEN(
            'Date'[Date],
            BLANK(),
            MAX('Date'[Date])
        ),
    'Sales Order'[Channel] = "Internet"
    )
VAR CustomersPrior =
    CALCULATE(
        DISTINCTCOUNT(Sales[CustomerKey]),
        DATESBETWEEN(
            'Date'[Date],
            BLANK(),
            MIN('Date'[Date]) - 1
        ),
        'Sales Order'[Channel] = "Internet"
    )
RETURN
    CustomersLTD - CustomersPrior

屏幕截图显示一个矩阵视觉对象,其中按“Year”和“Month”以及“Revenue”、“Revenue YTD”、“Revenue YoY %”和“New Customers”对行进行分组。突出显示了“New Customers”值。

对于 CustomersPrior 变量,请注意,DATESBETWEEN 函数包括筛选器上下文中的第一个日期 1 之前的日期。 由于 Power BI 在内部将日期存储为数字,因此可以加减数字来转换日期。

快照计算

偶尔,事实数据在时间上存储为快照。 常见示例包括库存水平或帐户余额。 值快照定期加载到表中。

汇总快照值时(例如库存水平),您可以汇总除日期之外的任何维度中的值。 在产品类别之间添加库存水平计数将生成有意义的摘要,但在日期之间添加库存水平计数则不会。 将昨天的库存水平添加到今天的库存水平并非有效操作(除非您想要计算该结果的平均值)。

在对快照表进行汇总时,度量值公式可以依赖于 DAX 时间智能函数来强制实施单个日期筛选器。

在以下示例中,您将探索 Adventure Works 公司的应用场景。 切换到模型视图,然后选择库存模型图。

屏幕截图显示一个模型图,该图由三个表组成:“Product”、“Date”和“Inventory”。“Product”和“Date”表都与“Inventory”表具有一对多关系。

请注意,该图表显示三个表:ProductDateInventoryInventory 表存储每个日期和产品的单位余额快照 重要的是,该表没有任何遗漏的日期,也不包含相同日期的任何产品的重复条目。 此外,最后一条快照记录的存储日期为 2020 年 6 月 15 日。

现在,切换到报表视图,然后选择报表的第 2 页。 将 Inventory 表的 UnitsBalance 列添加到矩阵视觉对象。 其默认摘要设置为值的总和。

屏幕截图显示一个标题为“FY2020 Mountain-200 Bike Stock”的矩阵视觉对象。它按“Product”对行进行分组,并按“Month”对列进行分组。显示每个产品和月份的较高值。

此视觉对象配置是一个示例,演示了如何不对快照值进行汇总。 将每日快照余额相加不会产生有意义的结果。 因此,从矩阵视觉对象中删除 UnitsBalance 字段。

现在,将向 Inventory 表添加用于将单个日期UnitsBalance 值相加的度量值。 该日期将为每个时间段的最后一个日期。 它通过使用 LASTDATE 函数来实现。 使用千位分隔符将度量值的格式设置为整数。

Stock on Hand =
CALCULATE(
    SUM(Inventory[UnitsBalance]),
    LASTDATE('Date'[Date])
)

注意

请注意,度量值公式使用 SUM 函数。 必须使用聚合函数(度量值不允许直接引用列),但如果每个日期的每个产品只有一行,则 SUM 函数将只对单个行进行运算。

Stock on Hand 度量值添加到矩阵视觉对象。 此时,每个产品的值将基于每个月最后记录的单位余额。

当前矩阵的屏幕截图,其中“June 2020”和“Total”列为空。

度量值为 2020 年 6 月返回空值,因为 6 月的最后一个日期不存在记录。 根据数据,还没有出现任何记录。

在筛选器上下文中按最后一个日期进行筛选存在固有问题:记录的日期可能不存在,因为该日期尚未发生,或者可能是因为周末未记录库存余额。

下一步是调整度量值公式,以确定包含非空结果 的最后一个日期,然后按该日期进行筛选。 您可以使用 LASTNONBLANK 函数实现此任务。

使用以下度量值定义修改 Stock on Hand 度量值。

Stock on Hand =
CALCULATE(
    SUM(Inventory[UnitsBalance]),
    LASTNONBLANK(
        'Date'[Date],
        CALCULATE(SUM(Inventory[UnitsBalance]))
    )
)

在矩阵视觉对象中,注意“June 2020”和“Total”的值(表示全年)。

屏幕截图显示矩阵视觉对象现在具有“June 2020”和“Total”的值。

LASTNONBLANK 函数是一个迭代程序函数。 它将返回生成非空结果的最后一个日期。 它通过以下方式实现此结果:按降序时间顺序 迭代浏览筛选器上下文中的所有日期。 (相反,FIRSTNONBLANK 将按顺序时间升序迭代。)对于每个日期,它都会对传入的表达式进行计算。 如果遇到非空结果,该函数将返回日期。 然后,使用该日期筛选 CALCULATE 函数。

注意

LASTNONBLANK 函数在行上下文中计算其表达式。 必须使用 CALCULATE 函数将行上下文转换为筛选器上下文,以正确计算表达式。

现在应隐藏 Inventory 表中的 UnitsBalance 列。 它将阻止报表作者对快照单位余额进行不适当的汇总。