好的。考慮以下...
DROP TABLE IF EXISTS ingredients;
CREATE TABLE ingredients
(ingredient_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,ingredient VARCHAR(30) NOT NULL UNIQUE
);
INSERT INTO ingredients (ingredient_id, ingredient) VALUES
(1, 'Macaroni'),
(2, 'Cheese'),
(3, 'Beans'),
(4, 'Toast'),
(5, 'Jam'),
(6, 'Jacket Potato'),
(7, 'Peanut Butter');
DROP TABLE IF EXISTS recipes;
CREATE TABLE recipes
(recipe_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,recipe VARCHAR(50) NOT NULL UNIQUE
);
INSERT INTO recipes (recipe_id, recipe) VALUES
(1, 'Macaroni & Cheese'),
(2, 'Cheese on Toast'),
(3, 'Beans on Toast'),
(4, 'Cheese & Beans on Toast'),
(5, 'Toast & Jam'),
(6, 'Beans & Macaroni'),
(9, 'Beans on Jacket Potato'),
(10, 'Cheese & Beans on Jacket Potato'),
(12, 'Peanut Butter on Toast');
DROP TABLE IF EXISTS recipe_ingredient;
CREATE TABLE recipe_ingredient
(recipe_id INT NOT NULL
,ingredient_id INT NOT NULL
,PRIMARY KEY (recipe_id,ingredient_id)
);
INSERT INTO recipe_ingredient (recipe_id, ingredient_id) VALUES
(1, 1),
(1, 2),
(2, 2),
(2, 4),
(3, 3),
(3, 4),
(4, 2),
(4, 3),
(4, 4),
(5, 4),
(5, 5),
(6, 1),
(6, 3),
(9, 3),
(9, 6),
(10, 2),
(10, 3),
(10, 6),
(12, 4),
(12, 7);
SELECT r.*
, GROUP_CONCAT(CASE WHEN i.ingredient IN ('Cheese','Beans') THEN i.ingredient END) i
, GROUP_CONCAT(CASE WHEN i.ingredient NOT IN('Cheese','Beans') THEN i.ingredient END) o
FROM recipes r
LEFT
JOIN recipe_ingredient ri
ON ri.recipe_id = r.recipe_id
LEFT
JOIN ingredients i
ON i.ingredient_id = ri.ingredient_id
GROUP
BY recipe_id;
+-----------+---------------------------------+--------------+---------------------+
| recipe_id | recipe | i | o |
+-----------+---------------------------------+--------------+---------------------+
| 1 | Macaroni & Cheese | Cheese | Macaroni |
| 2 | Cheese on Toast | Cheese | Toast |
| 3 | Beans on Toast | Beans | Toast |
| 4 | Cheese & Beans on Toast | Cheese,Beans | Toast |
| 5 | Toast & Jam | NULL | Toast,Jam |
| 6 | Beans & Macaroni | Beans | Macaroni |
| 9 | Beans on Jacket Potato | Beans | Jacket Potato |
| 10 | Cheese & Beans on Jacket Potato | Cheese,Beans | Jacket Potato |
| 12 | Peanut Butter on Toast | NULL | Toast,Peanut Butter |
+-----------+---------------------------------+--------------+---------------------+
小提琴的相同:http://www.sqlfiddle.com/#!2/45aa0/1
您定義了哪些索引?什麼是執行計劃('EXPLAIN SELECT ...')? – eggyal
我不知道這是否仍然是真實的(或曾經是......),但如果您將連接條件置於「ON」,mysql可能會更容易加入。 atm你在語義上要求''集合'中的每一行加入'tags'中的每一行,然後_then_過濾掉其中的一些。 – Eevee
@eggyal,所有表都將自己的id設置爲主索引。 – GoldenerAal