对于给定的一组容器记录,我需要找出哪些容器记录是其他容器的超集。
这是我的桌子:
bag
id | 名字 |
---|---|
1 | 包A |
2 | 包B |
3 | 包C |
4 | 包D |
item
id | 名字 |
---|---|
1 | 铅笔 |
2 | 笔 |
3 | 橡皮擦 |
4 | 标记 |
bag_item
(关联表)
id | bag_id | item_id |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 1 |
4 | 2 | 2 |
5 | 2 | 3 |
6 | 2 | 4 |
7 | 3 | 1 |
8 | 3 | 4 |
9 | 4 | 1 |
10 | 4 | 2 |
11 | 4 | 3 |
数据库:MySQL 8
我拥有“基本”
bag
标识符,并且我想要获得“超集”bag
标识符,其中包含我的“基本”包中的所有物品(以及更多物品,如果存在)。
如果我查询所有行李,响应应该如下所示:
base_bag_id | superset_bag_id |
---|---|
1 | 2 |
1 | 4 |
3 | 2 |
4 | 2 |
我尝试了以下方法来获得第 1 袋和第 4 袋的所有超级组:
select distinct base_bag_item.bag_id, superset_bag_item.bag_id
from bag_item as base_bag_item
join bag_item as superset_bag_item on superset_bag_item.item_id = base_bag_item.item_id
where superset_bag_item.bag_id != base_bag_item.bag_id
and base_bag_item.bag_id in (1, 4)
order by base_bag_item.bag_id, superset_bag_item.bag_id
但是,此查询将错误地生成包含“base”中的“至少一个”引号的包,例如bag id
3 将显示为 bag
id
1 的超集,因为两者都包含项目 id
1.如何获得我想要的输出?
SELECT
base.bag_id AS base_bag_id,
superset.bag_id AS superset_bag_id
FROM
(SELECT bag_id, item_id FROM bag_item) AS base
INNER JOIN
(SELECT bag_id, item_id FROM bag_item) AS superset
ON base.item_id = superset.item_id
WHERE base.bag_id <> superset.bag_id
GROUP BY base.bag_id, superset.bag_id
HAVING COUNT(DISTINCT base.item_id) =
(SELECT COUNT(DISTINCT item_id) FROM bag_item WHERE bag_id = base.bag_id)
AND COUNT(DISTINCT superset.item_id) >
(SELECT COUNT(DISTINCT item_id) FROM bag_item WHERE bag_id = base.bag_id)