Todos os extras podem estar no pacote ou não, tornando isso uma propriedade binária.
Uma maneira de visualizar a combinação é criar uma palavra com um bit para cada extra,
1
significa que o extra está na lista, 0
significa que não é.Por exemplo
Bench + undershelf + overshelf
é 110 (ou 011 se a string binária for lida na ordem oposta) Gerar todas as combinações de n bits fornecerá todas as combinações de n extras, também fornecerá todos os números de
0
para 2^n - 1
. Podemos trabalhar a partir daqui:
1. gerar a lista de números de
0
para 2^n - 1
;2. converter o número para binário, para listar a combinação de extras
3. combine cada bit com um extra
4. concatenar os nomes dos extras na descrição do pacote.
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
esta consulta funcionará até seis extras, então precisará de outra tabela de dígitos (um dígito a cada três extras).
Como funciona
A subconsulta
E
conte o número de extras, isso é usado em C
para limitar os elementos gerados pelas tabelas de dígitos u
e t
(unidade e dezenas) para 2^dim. O número é convertido em binário por
BIN(u.N + t.N * 10)
, em seguida, preenchido à esquerda com '0' para o número de elementos, gerando um bitmap de combinação. Para usar o bitmap gerado, cada extra precisa de um id falso que corresponda a uma posição nele, é o que a subconsulta
X
é destinado. As duas subconsultas são
JOIN
ed pelo enésimo caractere do bitmap:se o caractere for 1, o extra está no pacote, LEFT
unidos para não soltar o produto sem extras.