获取现有的客户产品库存清单并从产品中创建捆绑包

问题描述 投票:0回答:1

我正在研究 SQL Server 2019,并且有一个我正在尝试解决的问题,我可以将其最好地描述为“捆绑” - 最终结果是数据集显着缩小,并且需要跟踪的库存项目更少。 这是数据集的一个简单示例:

账户ID 产品编号
1000 10
1000 20
1000 30
1001 10
1001 20
1001 30
1001 50
1001 60
1001 70
1002 50
1002 60
1002 70
1003 80
1004 10
1004 20
1004 80

我创建了一个新表,其中“捆绑包”作为参考表:

捆绑包ID 产品编号
1 10
1 20
1 30
2 50
2 60
2 70
3 80

快速说明:为了使捆绑包出现在给定帐户 ID 上,捆绑包中的所有产品 ID 都必须存在。 我的目标是获得这种输出:

账户ID 捆绑包ID 捆绑包之外的产品数量
1000 1 0
1001 1 0
1001 2 0
1002 2 0
1003 3 0
1004 3 2

我希望消除/审查结果集中的任何异常值,即第三列中有数字的帐户 ID =/ 0

最初,我只是在制作捆绑包所在的实际表之前尝试使用案例,然后选择将产品选择放在 CTE 中。 我的第二种方法是将每个产品名称(第一个表的另一个列部分,名称是不同的)串在一起,并将列出帐户拥有的每个产品的扩展字符串关联为 CTE 中的新列。然后,如果帐户 ID 命中每个限定符(即 PRODUCTSTRING LIKE 'Product1' 和 ProductSTRING LIKE 'Product2' ......),则满足该情况。这种方法在最好的情况下感觉不稳定,在最坏的情况下感觉它只会在不知不觉中给我提供错误的结果。

到目前为止,我能想到的唯一其他方法是计算帐户 ID 拥有的唯一产品的数量,并将其与捆绑包的唯一产品的数量相匹配,然后基于此运行案例,但即便如此,感觉就像它很快就会变得非常笨重。

我正在使用的帐户 ID/产品 ID 视图大约有 1300 行。 谁能指出我没有考虑过的方法或我缺少的工具的方向?

sql sql-server sql-server-2019 relational-division
1个回答
0
投票

这首先是一种关系除法余数问题。您缺少

Account
Bundle
表,它们分别存储唯一值,我假设它们存在。

但是,要得到你想要的东西将非常困难,特别是考虑到问题的定义非常不明确。

如果您想知道应用单个

ProductsRemaining
后到底有多少个
Bundle
,您可以执行以下操作:

  • 交叉连接
    Account
    Bundle
  • 然后,在
    APPLY
    ...
  • ...采取
    AccountProduct
    Account
    ...
  • ...以及
    BundleProduct
    Bundle
    ...
  • ...并完全加入他们。
  • 删除任何缺少
    AccountProduct
    的内容,即存在没有匹配
    BundleProduct
    AccountProduct
  • 数一下没有
    AccountProduct
    BundleProduct
SELECT
  a.Id AS AccountId,
  b.Id AS BundleId,
  bp.*
FROM Account a
CROSS JOIN Bundle b
CROSS APPLY (
    SELECT
      COUNT(*) - COUNT(bp.ProductId) AS ProductsRemaining, COUNT(*) - COUNT(ap.ProductId) ap, count(*) c
    FROM (
        SELECT *
        FROM AccountProduct ap
        WHERE ap.AccountId = a.Id
    ) ap
    FULL JOIN (
        SELECT *
        FROM BundleProduct bp
        WHERE bp.BundleId = b.Id
    ) bp ON bp.ProductId = ap.ProductId
    HAVING COUNT(*) = COUNT(ap.ProductId)  -- no missing products
) bp;

db<>小提琴

从您的评论来看,当您希望能够采用

Bundle
的任何可能组合来组成产品时,问题就开始了,但我们不一定知道哪种组合。可能有多种可能的组合,有些可能是矛盾的。您可能需要某种程序语言的组合方法,尝试每种可能的捆绑组合。

例如,如果您将一个包含产品

1, 2
的捆绑包和另一个包含
2, 3
的捆绑包放在一起,会发生什么情况,对于包含产品
1, 2, 3
的帐户来说,这是一个有效的组合吗?

© www.soinside.com 2019 - 2024. All rights reserved.