Setiap ekstra dapat berada dalam bundel atau tidak, menjadikannya sebagai properti biner.
Cara memvisualisasikan kombinasi adalah dengan membuat kata dengan sedikit untuk setiap ekstra, 1
berarti ekstra ada dalam daftar, 0
maksudnya bukan.
Misalnya Bench + undershelf + overshelf
adalah 110 (atau 011 jika string biner dibaca dalam urutan yang berlawanan)
Menghasilkan setiap kombinasi n bit akan memberikan setiap kombinasi n tambahan, itu juga akan memberikan setiap angka dari 0
ke 2^n - 1
.
Kami dapat bekerja kembali dari sini:
1. buat daftar nomor dari 0
ke 2^n - 1
;
2. konversikan angka ke biner, untuk mencantumkan kombinasi ekstra
3. cocokkan setiap bit dengan ekstra
4. menggabungkan nama-nama ekstra dalam deskripsi bundel.
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
kueri ini akan bekerja hingga enam tambahan, maka itu akan membutuhkan tabel digit lain (satu digit setiap tiga tambahan).
Cara Kerjanya
Subkueri E
menghitung jumlah ekstra, ini digunakan dalam C
untuk membatasi elemen yang dihasilkan oleh tabel digit u
dan t
(satuan dan puluhan) menjadi 2^dim.
Nomor dikonversi ke biner dengan BIN(u.N + t.N * 10)
, lalu diisi dengan '0' ke jumlah elemen, menghasilkan bitmap kombinasi.
Untuk menggunakan bitmap yang dihasilkan setiap ekstra membutuhkan id palsu yang akan cocok dengan posisi di dalamnya, itulah yang subquery X
dimaksudkan untuk.
Kedua subquery tersebut adalah JOIN
diedit oleh char ke-n dari bitmap:jika char adalah 1 tambahan ada di bundel, LEFT
bergabung untuk tidak kehilangan produk tanpa tambahan.