Mysql
 sql >> Database >  >> RDS >> Mysql

Permutazione MySQL

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.