小编典典

MySQL排列

sql

我有两张桌子。一个拥有产品,另一个拥有捆绑产品。我需要弄清楚允许我找到所有可以出售附加产品的组合的SQL。

Products

Name   ID
Bench   1

Extra

Name           ID     Parent ID  QTY
undershelf     1        1        1
overshelf      2        1        1
wheels         3        1        1

我需要一个输出表,该表显示了我可以销售产品的所有组合:

Bench
Bench + undershelf
Bench + undershelf + overshelf
Bench + overshelf
Bench + wheels
bench + wheels + overshelf  and so one.

阅读 191

收藏
2021-03-23

共1个答案

小编典典

每个附加项都可以包含在捆绑包中,也可以不在捆绑包中,从而成为二进制属性。
可视化组合的一种方法是为每个多余项创建一个单词,1表示多余项在列表中,0表示不是。
例如Bench + undershelf + overshelf为110(如果二进制字符串以相反的顺序读取,则为011)

生成n位的每个组合都会给n个额外的组合,也会给从0到的每个数字2^n - 1

我们可以从这里开始工作:
1.生成从0到的数字列表2^n - 1
2.将数字转换为二进制,以列出附加项的组合
。3.将每个位与附加项匹配
。4.在捆绑包说明中串联附加项的名称。

SELECT CONCAT(b.Name
            , COALESCE(CONCAT(' + '
                            , GROUP_CONCAT(x.Name SEPARATOR ' + '))
                     , '')) Combination
FROM   (SELECT p.Name, p.id
                     , LPAD(BIN(u.N + t.N * 10), e.Dim, '0') bitmap
                FROM   Products p
                       CROSS JOIN (SELECT 0 N UNION ALL SELECT 1 
                         UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
                         UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7
                         UNION ALL SELECT 8 UNION ALL SELECT 9) u
                       CROSS JOIN (SELECT 0 N UNION ALL SELECT 1 
                         UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
                         UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7
                         UNION ALL SELECT 8 UNION ALL SELECT 9) t
                       INNER JOIN (SELECT COUNT(1) Dim
                                       , `Parent ID` pID
                                   FROM Extra) **E** ON e.pID = p.ID
                WHERE  u.N + t.N * 10 < Pow(2, e.Dim)
       ) **B**
       LEFT  JOIN (SELECT @rownum := @rownum + 1 ID
                        , `Parent ID` pID
                        , Name
                   FROM   Extra
                        , (Select @rownum := 0) r) **X**
                          ON x.pID = b.ID
                         AND SUBSTRING(b.bitmap, x.ID, 1) = '1'
GROUP BY b.Name, b.bitmap

此查询最多可以使用六个附加功能,然后需要另一个数字表(三个附加功能一个数字)。

怎么运行的

子查询 E 计算附加项的数量,用于 C 将数字表ut(单位和十进制)生成的元素限制为2 ^ dim。

该数字将通过转换为二进制BIN(u.N + t.N * 10),然后在元素数上保留“ 0”,从而生成一个组合位图。

要使用生成的位图,每个附加项都需要一个伪造的ID,该ID将与其中的位置匹配,这就是子查询 X 的目的。

这两个子查询JOIN由位图的第n个char进行编辑:如果char为1,则捆绑包中包含多余的字符,将其合并LEFT以不松散没有多余的产品。

2021-03-23