Skip to main content
added 164 characters in body
Source Link
Rick James
  • 79.4k
  • 5
  • 51
  • 117

Commalists, as you found, are a clumsy way to store lists. Instead, use a many-to-many mapping table:

CREATE TABLE toppings (
    pizza_id SMALLINT UNSIGNED NOT NULL,
    topping SMALLINT UNSIGNED NOT NULL,
    PRIMARY KEY(pizza_id, topping),
    INDEX(topping, pizza_id)
 ENGINE=InnoDB;

Then your task becomes simply

SELECT  a.pizza_id, a.topping
    FROM toppings AS a
    JOIN toppings AS b  ON b.topping = a.topping
                       AND b.pizza_id > a.pizza_id

To get the commalist (like you started with)

SELECT pizza_id, GROUP_CONCAT(topping)
    FROM toppings
    GROUP BY pizza_id;

Since it is unclear whether the question is

  • List all pizzas that have each topping. (The sample data does not have enough variety to bring out some issues with this.)

  • List all pairs of pizzas that have some toppings in common; and list the common toppings. I would expect the desired output for your sample data to be:

      1,2   4,6
    
  • Something else?

Commalists, as you found, are a clumsy way to store lists. Instead, use a many-to-many mapping table:

CREATE TABLE toppings (
    pizza_id SMALLINT UNSIGNED NOT NULL,
    topping SMALLINT UNSIGNED NOT NULL,
    PRIMARY KEY(pizza_id, topping),
    INDEX(topping, pizza_id)
 ENGINE=InnoDB;

Then your task becomes simply

SELECT  a.pizza_id, a.topping
    FROM toppings AS a
    JOIN toppings AS b  ON b.topping = a.topping
                       AND b.pizza_id > a.pizza_id

To get the commalist (like you started with)

SELECT pizza_id, GROUP_CONCAT(topping)
    FROM toppings
    GROUP BY pizza_id;

Commalists, as you found, are a clumsy way to store lists. Instead, use a many-to-many mapping table:

CREATE TABLE toppings (
    pizza_id SMALLINT UNSIGNED NOT NULL,
    topping SMALLINT UNSIGNED NOT NULL,
    PRIMARY KEY(pizza_id, topping),
    INDEX(topping, pizza_id)
 ENGINE=InnoDB;

To get the commalist (like you started with)

SELECT pizza_id, GROUP_CONCAT(topping)
    FROM toppings
    GROUP BY pizza_id;

Since it is unclear whether the question is

  • List all pizzas that have each topping. (The sample data does not have enough variety to bring out some issues with this.)

  • List all pairs of pizzas that have some toppings in common; and list the common toppings. I would expect the desired output for your sample data to be:

      1,2   4,6
    
  • Something else?

Source Link
Rick James
  • 79.4k
  • 5
  • 51
  • 117

Commalists, as you found, are a clumsy way to store lists. Instead, use a many-to-many mapping table:

CREATE TABLE toppings (
    pizza_id SMALLINT UNSIGNED NOT NULL,
    topping SMALLINT UNSIGNED NOT NULL,
    PRIMARY KEY(pizza_id, topping),
    INDEX(topping, pizza_id)
 ENGINE=InnoDB;

Then your task becomes simply

SELECT  a.pizza_id, a.topping
    FROM toppings AS a
    JOIN toppings AS b  ON b.topping = a.topping
                       AND b.pizza_id > a.pizza_id

To get the commalist (like you started with)

SELECT pizza_id, GROUP_CONCAT(topping)
    FROM toppings
    GROUP BY pizza_id;