Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Permutation

Jedes Extra kann im Bündel enthalten sein oder nicht, was es zu einer binären Eigenschaft macht.
Eine Möglichkeit, die Kombination zu visualisieren, besteht darin, ein Wort mit einem Bit für jedes Extra zu erstellen, 1 bedeuten, dass das Extra in der Liste ist, 0 bedeutet, dass es das nicht ist.
Zum Beispiel Bench + undershelf + overshelf ist 110 (oder 011, wenn die binäre Zeichenfolge in umgekehrter Reihenfolge gelesen wird)

Das Generieren jeder Kombination von n Bits ergibt jede Kombination von n Extras, es wird auch jede Zahl von 0 geben zu 2^n - 1 .

Von hier aus können wir zurückarbeiten:
1. Generieren Sie die Liste der Nummern aus 0 zu 2^n - 1;
2. Wandeln Sie die Zahl in eine Binärzahl um, um die Kombination der Extras aufzulisten.
3. passen Sie jedes Bit mit einem Extra an
4. Verketten Sie die Namen der Extras in der Bundle-Beschreibung.

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

Diese Abfrage funktioniert mit bis zu sechs Extras, dann benötigt sie eine weitere Zifferntabelle (eine Ziffer alle drei Extras).

So funktioniert es

Die Unterabfrage E zählen Sie die Anzahl der Extras, dies wird in C verwendet um die von den Zifferntabellen u generierten Elemente einzuschränken und t (Einer und Zehner) bis 2^dim.

Die Zahl wird durch BIN(u.N + t.N * 10) binär konvertiert , dann links mit '0' bis zur Anzahl der Elemente aufgefüllt, wodurch eine Kombinations-Bitmap generiert wird.

Um die generierte Bitmap zu verwenden, benötigen alle Extras eine gefälschte ID, die zu einer Position darin passt, das ist die Unterabfrage X ist gedacht für.

Die beiden Unterabfragen sind JOIN ed durch das n-te Zeichen der Bitmap:Wenn das Zeichen 1 ist, ist das Extra im Bündel, LEFT verbunden, um das Produkt nicht ohne Extras zu verlieren.