与调酒师问题相比,将“装有物品的袋子”视为“需要配料的饮料”,而“有物品的商店”就像“手头有配料的调酒师”。
这是一个合乎逻辑的解决方案,例如:
CREATE TABLE cms_user (
user_id int PRIMARY KEY
, name varchar(20)
);
INSERT INTO cms_user (user_id, name)
VALUES (1,'User1'), (2,'User2'), (3,'User3')
;
CREATE TABLE cms_user_ingredient_rs (
user_id int
, ingredient_id int
, PRIMARY KEY (user_id, ingredient_id)
);
INSERT INTO cms_user_ingredient_rs (user_id, ingredient_id)
VALUES (1,1), (1,2), (1,3), (1,5), (2,2), (2,3), (2,4)
, (3,1), (3,2), (3,3), (3,5), (3,6)
;
CREATE TABLE cms_drink (
drink_id int PRIMARY KEY
, name varchar(20)
);
INSERT INTO cms_drink (drink_id, name)
VALUES (10,'Test'), (15,'Test2')
;
CREATE TABLE cms_drink_ingredient_rs (
drink_id int
, ingredient_id int
, PRIMARY KEY (drink_id, ingredient_id)
);
INSERT INTO cms_drink_ingredient_rs (drink_id, ingredient_id)
VALUES (10,1), (10,3), (10,5), (15,1), (15,6)
;
WITH v2 AS (
SELECT t1.drink_id drink_id
, t1.ingredient_id ingredient_id
, v1.user_id user_id
FROM cms_drink_ingredient_rs AS t1
CROSS JOIN cms_user AS v1
)
SELECT v2.user_id, v2.drink_id
FROM v2
LEFT JOIN cms_user_ingredient_rs v3
ON (v2.ingredient_id,v2.user_id) = (v3.ingredient_id,v3.user_id)
GROUP BY v2.user_id, v2.drink_id
HAVING COUNT(if(v3.user_id IS NULL, 1, null))=0
;
+---------+----------+
| user_id | drink_id |
+---------+----------+
| 1 | 10 |
| 3 | 10 |
| 3 | 15 |
+---------+----------+
注意:还有其他解决方案。