Tutti gli extra possono essere nel bundle o meno, rendendola una proprietà binaria.
Un modo per visualizzare la combinazione è creare una parola con un bit per ogni extra, 1
significa che l'extra è nell'elenco, 0
significa che non lo è.
Ad esempio Bench + undershelf + overshelf
è 110 (o 011 se la stringa binaria viene letta nell'ordine opposto)
Generare ogni combinazione di n bit darà ogni combinazione di n extra, darà anche ogni numero da 0
a 2^n - 1
.
Possiamo lavorare da qui:
1. genera l'elenco di numeri da 0
a 2^n - 1
;
2. convertire il numero in binario, per elencare la combinazione di extra
3. abbina ogni bit con un extra
4. concatena i nomi degli extra nella descrizione del bundle.
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
questa query funzionerà fino a sei extra, quindi avrà bisogno di un'altra tabella di cifre (una cifra ogni tre extra).
Come funziona
La sottoquery E
conta il numero degli extra, questo è usato in C
per limitare gli elementi generati dalle tabelle di cifre u
e t
(unità e decine) a 2^dim.
Il numero viene convertito in binario da BIN(u.N + t.N * 10)
, quindi lasciato riempito con '0' al numero di elementi, generando una combinazione di bitmap.
Per utilizzare la bitmap generata, ogni extra ha bisogno di un ID falso che corrisponda a una posizione al suo interno, questo è ciò che la sottoquery X
è pensato per.
Le due sottoquery sono JOIN
ed dall'ennesimo carattere della bitmap:se il carattere è 1 l'extra è nel bundle, LEFT
uniti per non perdere il prodotto senza extra.