DAX 度量:从维度开始和结束日期开始的项目持续时间(天)

DAX measure: project duration (days) from dimension starting & ending date

我有以下经过简化的场景:

成本事实table:

date, project_key, costs €

项目维度:

project_key, name, starting date, ending date

日期维度:

date, years, months, weeks, etc

我需要创建一个度量,使用项目维度的开始和结束日期来告诉项目天数。 第一个 挑战是事实上 table 并非整天都没有交易。项目开始日期可能是 1 月 1 日,但第一笔成本交易实际上是 table,比如 1 月 15 日。因此,如果在过滤器上下文中,我们仍然需要计算开始日期和结束日期之间的天数。

所以第二个挑战是过滤上下文。用户可能只想查看二月。所以它的项目开始日期是 1.6.2016,结束日期是 1.11.2016,用户只想查看 9 月,它应该只显示 30 天。

第三个 挑战是查看多个项目的天数。因此,如果用户只选择一天,它应该查看所有正在进行的项目的计数。

感谢您提供的任何有助于解决问题的帮助。因此,如果需要,请不要犹豫,询问更多详情。

编辑:这里有一张图片可以更好地解释这一点:

更新 7.2.2017

仍在尝试为此解决方案创建单一度量。衡量哪些用户可以仅使用日期、项目或按原样使用。每天正在进行的项目计数的单独计算列将是简单的解决方案,但它只能按日期过滤 table。

2017 年 2 月 9 日更新

感谢大家的努力。作为最终结果,我相信不基于事实 table 的计算是非常棘手的。对于这个特定案例,我最终在日期和项目 ID 上使用 CROSS JOIN 进行了新的 table 以满足所有要求。一种选择是将开始日期和结束日期作为自己的行添加到事实 table 中,成本为零。真正的解决方案还有更多的维度需要我们考虑。

首先我会创建 2 个关系:

  1. project_dim[project_key] => costs_fact[project_key]
  2. date_dim[日期] => costs_fact[日期]

Costs 度量只是:SUM ( costs_fact[costs] )

持续时间(天)度量需要一个 CALCULATE 来更改日期维度上的筛选器上下文。这有效地计算了 project_dim 和 date_dim 之间的关系,基于从两个表中选择的行。

Duration (days) =
CALCULATE (
    COUNTROWS ( date_dim ),
    FILTER (
        date_dim,
        date_dim[date] >= MIN ( project_dim[starting_date] )
            && date_dim[date] <= MAX ( project_dim[ending_date] )
    )
)

我建议您将度量 Duration (days) 分成不同的计算 column/measure,因为它们在不同的上下文中实际上没有相同的含义。

首先,在dates/costs和projects/costs之间建立one-to-many关系。 (注意单交叉过滤方向,否则计算时会错误应用过滤上下文)

对于预期结果 1,我在日期维度中创建了一个名为 Project (days) 的计算列。它计算给定日期有多少项目在进行中。

Project (days) = 
COUNTROWS(
    FILTER(
        projects,
        dates[date] >= projects[starting_date] &&
        dates[date] <= projects[ending_date]
    )
)

P.S。如果您想在 weekly/monthly 基础上汇总结果,您可以进一步创建一个度量并汇总 Project (days).

对于预期结果 2 和 3,措施 Duration (days) 如下:

Duration (days) = 
COUNTROWS(
    FILTER(
        dates,
        dates[date] >= FIRSTDATE(projects[starting_date]) &&
        dates[date] <= FIRSTDATE(projects[ending_date])
    )
)

结果如预期:

要获得预期结果,您必须创建一个计算列和一个度量,计算列可以计算项目执行日期的项目数量,以及计算从 [=14 开始经过的天数的度量=] 和 [ending_date] 在每个项目中考虑过滤器。

必须使用此表达式在 dim_date table 中创建计算列:

Count of Projects =
SUMX (
    FILTER (
        project_dim,
        [starting_date] <= EARLIER ( date_dim[date] )
            && [ending_date] >= EARLIER ( date_dim[date] )
    ),
    1
)

应使用此表达式在 project_dim table 中创建度量:

Duration (Days) =
DATEDIFF (
    MAX ( MIN ( [starting_date] ), MIN ( date_dim[date] ) ),
    MIN ( MAX ( [ending_date] ), MAX ( date_dim[date] ) ),
    DAY
)
    + 1

你得到的结果是这样的:

如果您在 dim_date table

上使用切片器或过滤器过滤周

更新

对 SSAS 2014 的支持 - DATEDIFF() 在 SSAS 2016 中可用。

首先,重要的是您要意识到您正在衡量 两种不同的事物,但您只想让用户看到一种衡量方式。在第一个预期结果中,您希望获得每个日期的项目数量 运行,而在预期结果 2 和 3(在 OP 中)中,您希望每个项目经过的天数考虑 [=] 上的过滤器19=].

您可以创建一个度量,将两个度量合二为一,然后使用 HASONEFILTER 确定每个度量应该 运行 的上下文。在继续包装措施之前,请使用 DATEDIFF 功能在您的环境中不起作用,检查以下措施替代上面发布的措施。

在创建确定每个日期的项目数量所需的先前计算列后,创建一个名为 Duration Measure 的度量,您的用户不会使用此度量,但让我们计算最终的措施。

Duration Measure = SUMX(FILTER (
        date_dim,
        date_dim[date] >= MIN ( project_dim[starting_date] )
            && date_dim[date] <= MAX ( project_dim[ending_date] )
    ),1
)

现在你的用户应该交互的最终指标可以这样写:

Duration (Days) =
IF (
    HASONEFILTER ( date_dim[date] ),
    SUM ( date_dim[Count of Projects] ),
    [Duration Measure]
)

此度量将确定上下文并将return 是针对给定上下文的正确度量。因此,您可以为两个 table 添加相同的度量,它将 return 获得所需的结果。

尽管此解决方案在 Power BI 中进行了演示,但它也适用于 Power Pivot。