我的PowerPivot有问题。 让我们看看我的数据源中只有3列:
日期 - clientid - 类别
类别只能是1或2。 在数据源中,您可以在给定时间段内找到相同的clientid,有时候会有不同的类别。
因此,在我的数据透视表中,我可以根据所选的时间线看到我的客户的不同数量。 但是,当然,cat = 1和cat = 2的客户端总和大于不同的计数。 是否可以为每个clientid计算仅最新的条目,以便两只猫的总和与我的客户的不同数量相同?
提前感谢所有帮助我并为我消磨时间的人。
的Stefan
答案 0 :(得分:1)
这很有趣!谢谢你有趣的问题。通常,对于这类事情,我们可能会在额外字段中标记给定clientid的最新条目,但是您的日期过滤器选择需要在运行时动态显示。
我们走了。请注意,这是一种愚蠢的行为。
CountCat:=
COUNTROWS(
FILTER(
GENERATE(
VALUES( ClientCats[clientid] )
,CALCULATETABLE(
SAMPLE(
1
,SUMMARIZE(
ClientCats
,ClientCats[date]
,ClientCats[category]
)
,ClientCats[date]
,DESC
)
,ALL( ClientCats[category] )
)
)
,CONTAINS(
VALUES( ClientCats[category] )
,ClientCats[category]
,ClientCats[category]
)
)
)
让我们通过它。
COUNTROWS()是微不足道的。
FILTER()将表作为其第一个参数。它通过在此表中逐行迭代来创建行上下文。它计算每个行上下文中的布尔表达式,并返回表达式返回true的行。我们在这里暂时没有达到那种表达方式。让我们来看看我们要过滤的表格。
GENERATE()接受一个表作为输入,并通过在该表中逐行迭代来创建行上下文。对于每个行上下文,它计算第二个表,并交叉连接第一个表中当前行上下文中第二个表表达式中存在的行和第一个表中的行。
我们的第一个表是VALUES(ClientCats [clientid]),它只是透视表中上下文中所有[clientid]的独特列表。
然后我们为每个行上下文评估CALCULATETABLE(),也就是每个[clientid]。 CALCULATETABLE()计算由其第二个和后续参数确定的过滤器上下文中的表表达式。
SAMPLE()是我们评估的表格。 SAMPLE()就像TOPN(),但是非确定性地打破了关系。 SAMPLE(1,...)始终返回一行。 TOPN(1,...)返回与第一个位置相关的所有行。
此处的SAMPLE()将从SUMMARIZE()定义的表中返回一行。 SUMMARIZE()按名称中的表中的字段分组。因此,我们有一个表格,其中包含[date]和[category]的所有不同值,这些值基于我们的CALCULATETABLE()确定的上下文。 SAMPLE()的第三个参数定义了一个排序列,用于确定哪些行是第一个,第四个列确定排序顺序。因此,对于每个[clientid],我们将返回SUMMARIZE()中针对该[clientid]的最新行。
我们的CALCULATETABLE()中的ALL()从可能来自数据透视表的字段[类别]中删除上下文。这意味着每次我们评估我们的GENERATE()(记住我们仍然在这里的函数),我们得到一个表格,其中包含上下文中存在的所有[clientid],以及它们最近的[类别],即使我们正在过滤[类别]的透视单元格中进行评估。
这听起来像是一个问题 - 我们现在预计每个枢轴单元的计数都相同。这就是我们做COUNTROWS(GENERATE())时得到的结果。但是等等,我们仍然在FILTER()!
现在我们得到布尔表达式,它将过滤那个GENERATE()的行。 CONTAINS()将一个表作为其第一个参数,对该表中的列的引用作为其第二个参数,并将标量值作为其第三个参数。如果参数1中表的参数2中的列包含参数3中的值,则返回true。
我们在CALCULATETABLE()之外,因此[category]上存在上下文。 VALUES()返回上下文中的唯一行。在[类别]过滤的任何数据透视表单元格中,这将是1x1表格,但在我们的总计中,它将有多行。
因此,我们要测试的VALUES()中的列是[category](该VALUES()中唯一存在的列)。 我们要测试的值由ClientCats [category]引用。第三个参数评估由FILTER()确定的行上下文中的[category]。因此,对于与ClientCats [category]的当前过滤器上下文(在数据透视表单元格中)匹配的每一行,我们返回true。这里有令人费解的东西。
无论如何,结果是在[类别] - 过滤的透视单元格中,我们获得了在所选时间范围内具有[类别]值作为其最新类别的不同[clientid]的数量。 / p>
对于总计,我们在上下文中得到每个[clientid]。
这可能没有非常好的表现曲线。
Here's a sample workbook to play with the functioning measure defined.
修改
根据以下回复。
您是否需要在模型中维护具有[UseClient]<>的所有行? 1?除Power Pivot之外的工具中,重复数据删除和标记总是更容易。
我不知道你如何确定[UseClient]中1的值。没有是给定[ClientID]的最新条目。如果你只想标记最新的行,这听起来像你想要的那样,而不是你的工作簿的样子,你可以比在一个小节中这样做更容易地做一个计算列:
=SAMPLE(
1
,CALCULATETABLE( // return all dates for the [clientid] on current row
VALUES( ClientCats[date] )
,ALLEXCEPT( ClientCats, ClientCats[clientid] )
)
,ClientCats[date]
,DESC
) = ClientCats[date] // row context in table
当给定行上[date]的值等于该行上客户端的最大[date]时,这将返回true。
您可以轻松地在Power Query中执行的一项操作是将[clientid]分组并为每个[clientid]取最大日期。然后每个客户端有一行。
这与原始问题完全不同,因为您的原始版本希望根据日期选择找到最大值。但是,计算列不会根据过滤器上下文进行更新。它只在模型刷新时重新计算。如果您愿意使用计算列,那么在将数据问题带入Power Pivot之前,只需处理您的数据问题。