我在SQL中表示项目集(SQLite,如果相关)。我的表看起来像这样:
ITEMS表:
| ItemId | Name |
| 1 | Ginseng |
| 2 | Honey |
| 3 | Garlic |
项集:
| ItemSetId | Name |
| ... | ... |
| 7 | GinsengHoney |
| 8 | HoneyGarlicGinseng |
| 9 | Garlic |
ITEMSETS2ITEMS
| ItemsetId | ItemId |
| ... | .... |
| 7 | 1 |
| 7 | 2 |
| 8 | 2 |
| 8 | 1 |
| 8 | 3 |
如您所见,Itemset可能包含多个Items,这种关系在Itemset2Items表中有详细说明。
如何检查表中是否已有新项目集,如果是,请查找其ID?
例如,我想检查“人参,大蒜,蜂蜜”是否为现有项目集。所需答案为“是”,因为存在单个ItemsetId,其中包含完全这三个ID。请注意,该集合是无序的:对“蜂蜜,大蒜,人参”的查询应该表现相同。
我该怎么做?
答案 0 :(得分:1)
我建议您首先将要检查的项目集放入表格中,每个项目一行。
现在的问题是这个“提议的”项目集与其他项目集的重叠。以下查询提供了答案:
select itemsetid,
from (select coalesce(ps.itemid, is2i.itemid) as itemid, is2i.itemsetid,
max(case when ps.itemid is not null then 1 else 0 end) as inProposed,
max(case when is2i.itemid is not null then 1 else 0 end) as inItemset
from ProposedSet ps full outer join
ItemSets2items is2i
on ps.itemid = is2i.itemid
group by coalesce(ps.itemid, is2i.itemid), is2i.itemsetid
) t
group by itemsetid
having min(inProposed) = 1 and min(inItemSet) = 1
这将所有项目集加入所有项目集。然后,它按每个项目集中的项目进行分组,并给出关于项目是否在集合中的标记。最后,它检查项目集中的所有项目是否都在。
答案 1 :(得分:0)
听起来你需要找到一个ItemSet
:
Item
Item
s 此示例将返回此类项集的ID(如果存在)。
注意:此解决方案适用于MySQL,但是一旦您将@variable
更改为SQLite理解的内容,它就可以在SQLite中运行,例如:绑定变量。
-- these are the IDs of the items in the new itemset
-- if you add/remove some, make sure to change the IN clauses below
set @id1 = 1;
set @id2 = 2;
-- this is the count of items listed above
set @cnt = 2;
SELECT S.ItemSetId FROM ItemSets S
INNER JOIN
(SELECT ItemsetId, COUNT(*) as C FROM ItemSets2Items
WHERE ItemId IN (@id1, @id2)
GROUP BY ItemsetId
HAVING COUNT(*) = @cnt
) I -- included ingredients
ON I.ItemsetId = S.ItemSetId
LEFT JOIN
(SELECT ItemsetId, COUNT(*) as C FROM ItemSets2Items
WHERE ItemId NOT IN (@id1, @id2)
GROUP BY ItemsetId
) A -- additional ingredients
ON A.ItemsetId = S.ItemSetId
WHERE A.C IS NULL
请参阅fiddle for MySQL。