我有两张桌子。一个拥有产品,另一个拥有捆绑产品。我需要弄清楚允许我找到所有可以出售附加产品的组合的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.
每个附加项都可以包含在捆绑包中,也可以不在捆绑包中,从而成为二进制属性。 可视化组合的一种方法是为每个多余项创建一个单词,1表示多余项在列表中,0表示不是。 例如Bench + undershelf + overshelf为110(如果二进制字符串以相反的顺序读取,则为011)
1
0
Bench + undershelf + overshelf
生成n位的每个组合都会给n个额外的组合,也会给从0到的每个数字2^n - 1。
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 将数字表u和t(单位和十进制)生成的元素限制为2 ^ dim。
E
C
u
t
该数字将通过转换为二进制BIN(u.N + t.N * 10),然后在元素数上保留“ 0”,从而生成一个组合位图。
BIN(u.N + t.N * 10)
要使用生成的位图,每个附加项都需要一个伪造的ID,该ID将与其中的位置匹配,这就是子查询 X 的目的。
X
这两个子查询JOIN由位图的第n个char进行编辑:如果char为1,则捆绑包中包含多余的字符,将其合并LEFT以不松散没有多余的产品。
JOIN
LEFT