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

Customer List with invoice which has all selected items

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

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

我们来分解一下。

COUNTROWS() 按照它说的做,计算 table.

中的行数

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

我们的 table 参数是 DimCustomer。 DimCustomer 将根据数据透视表的筛选上下文进行筛选(例如,如果您 select 客户子集,则只会考虑该子集)。

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

CALCULATE() 在由其第二个到最后一个参数定义的过滤器上下文中评估其第一个参数。我们正在为当前客户计算 FactSale[ProductKey] 中的不同值(当前在迭代中通过 FILTER() 的每一行),受制于它们存在于 table TargetProduct 中的约束。

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

因此,我们将 return 购买了所有目标产品的 table 客户。在数据透视表中的客户级别,这将为每个客户 return 1 或空白。 Pivot tables 自动禁止显示带有度量空白的行标签,因此您只会看到购买了所有目标产品的客户。

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

如果您有不同的目标群体,这也将支持 selectTargetProduct 的子集。

下面是我的模型和示例数据的图像,以及显示整个事物正常运行的枢轴 table。

编辑

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

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

SUMMARIZE() 将 table 作为其第一个参数和要分组的字段列表。它还可以添加计算列并对这些列进行汇总,但我们不需要那样做。较新版本的 Power Pivot (Excel 2016) 有一个 syntax-equivalent GROUPBY() 执行分组以获得潜在的(小的)性能改进。我们只需对 InvoiceKey 和 CustomerKey 进行分组,然后进行与之前相同的过滤。

这确实改变了 return 值的性质。以前,计数是购买整套目标产品的客户数量。由于我们现在也在发票上分组,因此计数将是购买所有目标的 customer-invoice 对的数量。由于您的要求只是简单地列出了客户,因此该措施仍然可以满足他们。不过,对于特定客户,您可能会看到大于 1 的数字。您仍然会在忽略不符合条件的客户的数据透视表中有这种行为。

这是我使用此度量执行更改后的示例数据的图片。请注意,Customer6 现在已经购买了所有三个目标,但使用的是单独的发票。 Customer3 仍然出现,因为所有三个都在一张发票上。