仅根据过滤器上下文计算多个的最新实例

时间:2018-07-12 21:53:52

标签: ssas powerbi dax powerpivot excel-2016

我有大量的事件在车辆清单中发生,这些事件会影响它们的使用状态或停用状态。我想创建一个可以根据此表中的事件在任何时间点计算各种清单中车辆数量的度量。

此表从SQL数据库中提取到Excel 2016工作表中,我正在使用PowerPivot尝试提出DAX度量。

以下是一些示例数据event_list

vehicle_id    event_date    event         event_sequence    inventory
100           2018-01-01    purchase      1                 in-service
101           2018-01-01    purchase      1                 in-service
102           2018-02-04    purchase      1                 in-service
100           2018-02-07    maintenance   2                 out-of-service
101           2018-02-14    damage        2                 out-of-service
101           2018-02-18    repaired      3                 in-service
100           2018-03-15    repaired      3                 in-service
102           2018-05-01    damage        2                 out-of-service
103           2018-06-03    purchase      1                 in-service

我希望能够在Excel中创建数据透视表(或使用CUBE函数等)来获得如下输出表:

date          in-service     out-of-service
2018-02-04    3              0
2018-02-14    1              2
2018-03-15    3              0
2018-06-03    3              1

基本上,我希望能够根据任何时间来计算广告资源。该示例只有几个日期,但希望可以提供足够的图片。

到目前为止,我基本上已经提出了这个建议,但是它计算出的车辆数量超过了预期的数量-我无法弄清楚如何仅获取最新的event_sequence或event_date并将其用于盘点。

cumulative_vehicles_at_date:=CALCULATE(
    COUNTA([vehicle_id]),
    IF(IF(HASONEVALUE (event_list[event_date]), VALUES (event_list[event_date]))>=event_list[event_date],event_list[event_date])
)

我尝试使用MAX()和EARLIER()函数,但它们似乎不起作用。

编辑:添加了PowerBI标签,因为我现在正在使用该软件来尝试解决此问题。查看有关亚历克西斯·奥尔森答案的评论。

2 个答案:

答案 0 :(得分:0)

这非常困难。我没有一个很好的答案,但这是一些类似的工作。

您将创建一个新的计算表,您将在其中计算每个日期的每辆车的状态。从每个车辆和每个日期的基础交叉连接开始:

= CROSSJOIN(VALUES(event_list[vehicle_id]), VALUES(event_list[event_date]))

然后添加一个计算列以查找该日期每个车辆的最大序列号。

Sequence = MAXX(
               FILTER(event_list,
                   event_list[event_date] <= Cross[event_date] &&
                   event_list[vehicle_id] = Cross[vehicle_id]),
               event_list[event_sequence])

现在您可以使用另一列计算出的列查找每个车辆/序列对的库存值:

Inventory = LOOKUPVALUE(
                event_list[inventory],
                event_list[vehicle_id], Cross[vehicle_id],
                event_list[event_sequence], Cross[Sequence]) 

结果应如下所示:

Cross Table

一旦有了这个,就可以使用此计算表来创建矩阵。将event_date放在行上,将Inventory放在列上。在可视级过滤器中过滤出空白的库存值,并将vehicle_id放入值字段,使用计数或非重复计数作为汇总方法(而不是默认总和)。

它应该像这样:

Result

答案 1 :(得分:0)

我认为我找到了一种比以前更干净的方法。


让我们在event_list表上添加两列。一种在该日期计算车辆"in-service",另一种在该日期计算车辆"out-of-service"

InService = 
    VAR Summary = SUMMARIZE(
                      FILTER(event_list,
                          event_list[event_date] <= EARLIER(event_list[event_date])),
                      event_list[vehicle_id],
                      "MaxSeq", MAX(event_list[event_sequence]))

    VAR Filtered = FILTER(event_list,
                       event_list[event_sequence] =
                           MAXX(
                               FILTER(Summary,
                                   event_list[vehicle_id] = EARLIER(event_list[vehicle_id])),
                               [MaxSeq]))

    RETURN SUMX(Filtered, 1 * (event_list[inventory] = "in-service"))

您可以为OutOfService创建一个类似的计算列,也可以将总数减去InService来计算。

OutOfService =
    CALCULATE(
        DISTINCTCOUNT(event_list[vehicle_id]),
        FILTER(event_list,
            event_list[event_date] <= EARLIER(event_list[event_date])))
    - event_list[InService]

Data Table

现在,您所要做的就是将event_date放在矩阵可视行部分,并将InServiceOutOfService列添加到values部分(对聚合选项使用Maximum或Minimum)而不是总和。

Output


这是计算列InService背后的逻辑:

我们首先创建一个Summary表,该表计算每辆车的最大event_sequence值。 (我们过滤event_date仅考虑到当前使用的日期。)

现在我们知道每辆车的最后一个event_sequence值是什么,我们用它来将整个表格向下过滤到仅与那些车辆和序列值相对应的行。过滤器逐行浏览表格,并检查序列值是否与我们在Summary表中计算出的值匹配。请注意,当我们仅将Summary表过滤为当前正在使用的车辆时,只会得到一行。我只是使用MAXX来提取[MaxSeq]值。 (有点像使用LOOKUPVALUE,但不能在变量上使用它。)

现在,我们已将表格仅过滤为每辆车的最新事件,我们要做的就是计算其中"in-service"个事件的数量。我在这里使用了SUMX,其中1*(True/False)强制布尔值返回10