Power BI技术问询:DAX/Power Query如何按客户展示未销售产品?
解决方案:按客户展示未销售产品(DAX/Power Query两种实现)
核心逻辑
要实现需求,本质是先生成「所有客户×所有可用产品」的完整组合,再剔除其中已存在于销售记录里的组合。两种方案各有适用场景,按需选择即可。
方案一:Power Query(适合生成静态表加载到模型)
步骤如下:
- 补全产品表:确保你的「产品表」包含所有可用产品(你的示例期望输出里有Product3/4,所以产品表需要补充这两个条目)。
- 生成客户-产品全组合:
- 在Power Query中选中「客户表」,点击添加列 > 自定义列,输入公式:
= Products(Products为你的产品表名称) - 展开这个自定义列,得到所有客户与所有产品的笛卡尔积
- 在Power Query中选中「客户表」,点击添加列 > 自定义列,输入公式:
- 左连接销售表:
- 将全组合表和逆透视后的销售表做左连接,连接条件为
Customer列匹配,且全组合表的Product列匹配销售表的Sold Products列
- 将全组合表和逆透视后的销售表做左连接,连接条件为
- 筛选未销售记录:
- 筛选连接后表中「Sold Products」列为空的行,这些就是对应客户未销售的产品
- 最后保留
Customer和Product列,重命名列名匹配你的期望输出
对应的Power Query M代码示例(替换表名和列名即可用):
let // 加载客户表 Customers = Table.FromRecords({ [Customer = "Customer 1"], [Customer = "Customer 2"] }), // 加载完整产品表(包含所有可用产品) Products = Table.FromRecords({ [Product = "Product 1"], [Product = "Product 2"], [Product = "Product 3"], [Product = "Product 4"] }), // 生成客户-产品全组合 FullCombination = Table.AddColumn(Customers, "Product", each Products), FullCombinationExpanded = Table.ExpandTableColumn(FullCombination, "Product", {"Product"}, {"Product"}), // 加载销售表 Sales = Table.FromRecords({ [Customer = "Customer 1", Sold Products = "Product 1"], [Customer = "Customer 1", Sold Products = "Product 2"], [Customer = "Customer 2", Sold Products = "Product 3"], [Customer = "Customer 3", Sold Products = "Product 4"] }), // 左连接销售表 Joined = Table.NestedJoin(FullCombinationExpanded, {"Customer", "Product"}, Sales, {"Customer", "Sold Products"}, "Sales", JoinKind.LeftOuter), // 展开销售表标记列 JoinedExpanded = Table.ExpandTableColumn(Joined, "Sales", {"Sold Products"}, {"Sold Products"}), // 筛选未销售记录 Filtered = Table.SelectRows(JoinedExpanded, each [Sold Products] = null), // 清理并重命名列 Final = Table.RenameColumns(Table.RemoveColumns(Filtered, {"Sold Products"}), {{"Product", "Products Possible to Sold to each Customer"}}) in Final
方案二:DAX(适合动态交互场景,比如配合切片器)
如果需要报表随筛选条件动态更新(比如选特定客户后自动展示其未销售产品),用DAX实现更灵活:
方式1:创建计算表
直接生成包含所有客户未销售产品的表:
未销售产品表 = VAR AllCustomerProduct = CROSSJOIN(VALUES('客户表'[Customer]), VALUES('产品表'[Product])) VAR SoldCustomerProduct = VALUES('销售表'[Customer], '销售表'[Sold Products]) RETURN EXCEPT(AllCustomerProduct, SoldCustomerProduct)
生成后可手动重命名列名匹配期望输出。
方式2:用度量值配合矩阵展示
无需单独建表,在矩阵中通过度量值筛选展示:
未销售产品 = IF( NOT(SELECTEDVALUE('产品表'[Product]) IN VALUES('销售表'[Sold Products])), SELECTEDVALUE('产品表'[Product]), BLANK() )
使用时将「客户」放矩阵行,「未销售产品」放矩阵值,筛选掉空白值即可。
关键注意事项
- 产品表必须包含所有可用产品,否则无法得到完整的未销售产品列表
- Power Query生成的是静态表,客户或产品更新后需手动刷新查询;DAX计算表会随模型数据自动更新
内容的提问来源于stack exchange,提问作者Den10102020
相关产品推荐
相关产品推荐

