MySQL permutation

前端 未结 3 767
攒了一身酷
攒了一身酷 2021-01-03 06:15

I have two tables. One has products and the other has bundles that go with it. I need to figure out the SQL that allows me to find all the combinations in which I can sell

3条回答
  •  生来不讨喜
    2021-01-03 07:10

    Possible entirely within MySQL, though not simple. This example can handle up to 5 "extras", and is easily extensible for more:

    CREATE TABLE products (name varchar(100), id int primary key);
    INSERT INTO products (name, id) VALUES ('Bench', 1);
    
    CREATE TABLE extra (name varchar(100), id int primary key, parent_id int references products.id, qty int);
    INSERT INTO extra (name, id, parent_id, qty) VALUES 
      ('undershelf', 1, 1, 1), ('overshelf', 2, 1, 1), ('wheels', 3, 1, 1);
    
    CREATE TABLE boolean_values (x boolean);
    INSERT INTO boolean_values VALUES (TRUE), (FALSE);
    
    CREATE VIEW product_extras_interim_vw AS
    SELECT p.id product_id, p.name product_name, e.id extra_id, e.name extra_name, x
      FROM products p
      JOIN extra e ON (e.parent_id = p.id)
      CROSS JOIN boolean_values;
    
    SELECT DISTINCT a.product_name
    , CASE WHEN a.x THEN CONCAT(' + ', a.extra_name) END extra1
        , CASE WHEN b.x THEN CONCAT(' + ', b.extra_name) END extra2
        , CASE WHEN c.x THEN CONCAT(' + ', c.extra_name) END extra3
        , CASE WHEN d.x THEN CONCAT(' + ', d.extra_name) END extra4
        , CASE WHEN e.x THEN CONCAT(' + ', e.extra_name) END extra5
    FROM product_extras_interim_vw a
    LEFT JOIN product_extras_interim_vw b
      ON ( a.product_id = b.product_id
          AND b.extra_id > a.extra_id
      AND a.x )
    LEFT JOIN product_extras_interim_vw c
      ON ( a.product_id = c.product_id
      AND c.extra_id > b.extra_id
          AND b.x )
    LEFT JOIN product_extras_interim_vw d
      ON ( a.product_id = d.product_id
          AND d.extra_id > c.extra_id
          AND c.x)
    LEFT JOIN product_extras_interim_vw e
      ON ( a.product_id = e.product_id
          AND e.extra_id > d.extra_id
          AND d.x)
    ORDER BY product_name, extra1, extra2, extra3, extra4, extra5;
    

    Output:

    Bench
    Bench + overshelf
    Bench + overshelf + wheels
    Bench + undershelf
    Bench + undershelf + overshelf
    Bench + undershelf + overshelf + wheels
    Bench + undershelf + wheels
    Bench + wheels
    

提交回复
热议问题