Elke extra's kan in de bundel zitten of niet, waardoor dat een binaire eigenschap is.
Een manier om de combinatie te visualiseren is om een woord te maken met een bit voor elke extra, 1
betekent dat de extra in de lijst staat, 0
bedoel dat het niet zo is.
Bijvoorbeeld Bench + undershelf + overshelf
is 110 (of 011 als de binaire string in de tegenovergestelde volgorde wordt gelezen)
Het genereren van elke combinatie van n bit geeft elke combinatie van n extra's, het geeft ook elk nummer vanaf 0
naar 2^n - 1
.
We kunnen vanaf hier terug werken:
1. genereer de lijst met nummers van 0
naar 2^n - 1
;
2. converteer het getal naar binair, om de combinatie van extra's weer te geven
3. match elk beetje met een extra
4. voeg de namen van de extra's samen in de bundelbeschrijving.
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
deze zoekopdracht werkt tot zes extra's, daarna heeft het een andere cijfertabel nodig (één cijfer per drie extra's).
Hoe het werkt
De subquery E
tel het aantal extra's, dit wordt gebruikt in C
om de elementen te beperken die worden gegenereerd door de cijfertabellen u
en t
(eenheid en tientallen) naar 2^dim.
Het getal wordt omgezet naar binair door BIN(u.N + t.N * 10)
, dan links opgevuld met '0' voor het aantal elementen, waardoor een combinatiebitmap wordt gegenereerd.
Om de gegenereerde bitmap te gebruiken, hebben elke extra's een nep-ID nodig die overeenkomt met een positie erin, dat is wat de subquery X
is bedoeld voor.
De twee subquery's zijn JOIN
ed door de n-de char van de bitmap:als de char 1 is, zit de extra in de bundel, LEFT
samengevoegd om het product niet te verliezen zonder extra's.