包含所有选定项目的发票的客户列表

时间:2016-01-06 04:57:35

标签: powerpivot dax

我有DimProduct表,DimCustomer表和FactSales表。 有一个目标产品列表。 我想列出在一张发票中购买目标产品列表的所有产品的客户。 我该怎么做?我没有线索。请给我一些建议。

1 个答案:

答案 0 :(得分:1)

CustomersWithAllTargets:=
COUNTROWS(
    FILTER(
        DimCustomer
        ,CALCULATE(
            DISTINCTCOUNT( FactSale[ProductKey] )
            ,TargetProduct
        ) = DISTINCTCOUNT( TargetProduct[ProductKey] )
    )
)

让我们打破这一点。

COUNTROWS()执行它所说的并计算表中的行。

我们想要计算其行的表是我们的FILTER()的结果。 FILTER()将表表达式作为其第一个参数,通过迭代该表表达式中的每一行来创建行上下文。对于每一行,将计算其第二个参数中的表达式。只有表中第二个参数的计算结果为true的行才包含在输出中。

我们的表参数是DimCustomer。 DimCustomer将通过pivot的过滤器上下文进行过滤(例如,如果您选择一个客户子集,则只会考虑该子集)。

对于每个客户,我们评估CALCULATE()。

CALCULATE()计算其第二个到第二个参数定义的过滤器上下文中的第一个参数。我们在FactSale [ProductKey]中为当前客户计算不同的值(迭代通过FILTER()每行的当前值),但受TargetProduct表中存在的约束条件的限制。

我们正在测试该CALCULATE()(当前客户购买了多少目标产品)的价值,以及TargetProduct [ProductKey]中的值计数。当它们相同时,客户已经购买了所有产品。当它们不相等时,客户就没有了。

因此,我们将返回已购买所有目标产品的客户表。在枢轴中的客户级别,每个客户将返回1或空白。数据透视表会自动禁止显示带有空白的行标签,因此您只能看到已购买所有目标产品的客户。

总计将告诉您有多少客户购买了所有目标。

如果你有不同的目标群体,这也将支持选择TargetProduct的子集。

下面是我的模型和样本数据的图像,以及显示整个行为正确的数据透视表。

enter image description here

修改

我们将使用另外一个函数来分组多个字段SUMMARIZE()。

CustomersWithAllTargets:=
COUNTROWS(
    FILTER(
        SUMMARIZE(
            FactSale
            ,FactSale[InvoiceKey]
            ,FactSale[CustomerKey]
        )
        ,CALCULATE(
            DISTINCTCOUNT( FactSale[ProductKey] )
            ,TargetProduct
        ) = DISTINCTCOUNT( TargetProduct[ProductKey] )
    )
)

SUMMARIZE()将一个表作为其第一个参数和一个要分组的字段列表。它还可以添加计算列并对这些列进行汇总,但我们并不需要。较新版本的Power Pivot(Excel 2016)具有语法等效的GROUPBY(),可执行分组以实现潜在(小)性能改进。我们只需对InvoiceKey和CustomerKey进行分组,并进行与之前相同的过滤。

这确实会改变返回值的性质。以前计算的数量是购买了整套目标产品的客户数量。由于我们现在还在发票上进行分组,因此计数将是已购买所有目标的客户发票对的数量。由于您的要求仅仅列为列出客户,因此该措施仍然符合这些要求。但是,您可能会看到特定客户的数字> 1。您仍然会忽略不符合条件的客户。

这是我使用此措施执行的更改后的样本数据的图片。请注意,Customer6现在已经购买了所有三个目标,但是在单独的发票上。客户3仍然显示,因为所有三个都在1张发票上。

enter image description here