sql >> Database >  >> RDS >> Mysql

MySQL-permutatie

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.



  1. Hoe krijg je een kolom met mysql_query-resultaten in een array?

  2. Schrijf snel panda's dataframe naar postgres

  3. SIGN() Functie in Oracle

  4. Parameter gebruiken als kolomnaam in Postgres-functie