我有一张清单,上面有库存动向。每个库存项目都有唯一的ID,并且它们会随着时间变化(例如,状态A,B,C和D,但并非总是以此顺序)。 ID的每个状态更改都是表中带有状态更改时间戳的新记录。我的目标是使用Power BI DAX计算某一天处于状态“ B” 的库存数量。逻辑是计算不同ID的数量,这些ID在特定日期之前违反状态“ B”,但在该日期之前没有任何新状态。
源表示例:
ID | TimeStamp | Status
1 | 8/20/2018 | A
1 | 8/21/2018 | B
1 | 8/24/2018 | C
2 | 8/19/2018 | A
2 | 8/20/2018 | B
2 | 8/22/2018 | C
2 | 8/24/2018 | D
3 | 8/18/2018 | A
3 | 8/21/2018 | B
4 | 8/15/2018 | A
4 | 8/17/2018 | B
4 | 8/24/2018 | D
输出表示例:
Date | Count of Items in Status B on this Day
8/17/2018 | 3
8/18/2018 | 2
8/19/2018 | 0
8/20/2018 | 8
8/21/2018 | 10
8/22/2018 | 5
8/23/2018 | 3
我当时正在考虑为每个ID为状态为“ B”的最新时间戳创建一个表,然后在状态“ B”的时间戳之后查找下一个时间戳(如果适用):
ID (primary key) | TimeStamp of 'B' breached | TimeStamp of next status breach
1 | 8/20/2018 | 8/21/2018
2 | 8/18/2018 | 8/22/2018
3 | 8/21/2018 |
4 | 8/15/2018 | 8/20/2018
然后,我将上面的数据插入Date上下文,并计算上表中ID的数量,其中“ 'B'的时间戳”违反了”值,而“ 下一个状态违反的时间戳”值大于特定日期。
不幸的是,我不确定如何将此逻辑插入DAX语法中,因此任何建议将不胜感激。
非常感谢! 盖尔格
答案 0 :(得分:3)
这有点棘手,但是我们可以使用度量内的临时计算摘要表来做到这一点:
CountStatusB =
SUMX(
ADDCOLUMNS(
SUMMARIZE(
FILTER(
ALL(Inventory),
Inventory[TimeStamp] <= MAX(Inventory[TimeStamp])
),
Inventory[ID],
"LastTimeStamp",
MAX(Inventory[TimeStamp])
),
"Status",
LOOKUPVALUE(Inventory[Status],
Inventory[ID], Inventory[ID],
Inventory[TimeStamp], [LastTimeStamp])
),
IF([Status] = "B",
1,
0
)
)
首先,我们创建一个摘要表,该表为每个TimeStamp
值计算最后一个ID
。为此,我们在经过过滤的表上使用SUMMARIZE
函数,在该表中,我们仅考虑来自当前日期或更早的日期,按ID
分组,并计算最大值TimeStamp
。
一旦我们在当天的每个TimeStamp
中拥有最大的ID
,我们可以查询当天Status
的情况,并将其作为一列添加到汇总表中。
一旦我们知道当日每个Status
的最新ID
,我们只需要总结Status
是"B"
的那些CountB =
VAR CurrDay = MAX(Inventory[TimeStamp])
VAR Summary = SUMMARIZE(
FILTER(
ALL(Inventory),
Inventory[TimeStamp] <= CurrDay
),
Inventory[ID],
"LastTimeStamp",
MAX(Inventory[TimeStamp])
)
VAR LookupStatus = ADDCOLUMNS(
Summary,
"Status",
LOOKUPVALUE(Inventory[Status],
Inventory[ID], Inventory[ID],
Inventory[TimeStamp], [LastTimeStamp]
)
)
RETURN SUMX(LookupStatus, IF([Status] = "B", 1, 0))
,而忽略其他的。
如果我们将其分解为若干步骤,则可能更容易阅读该度量。这与以前的逻辑相同,但是使用变量更加清楚。
java net.sf.saxon.functions.UnparsedText input.xml