2012-07-29 52 views
1

我代表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  | 

正如你所看到的,一個套裝可以包含多個項目,並這個關係在Itemset2Items表中詳細說明。

我該如何檢查一個新的項目集是否已經在表中,如果有,找到它的ID?

例如,我想檢查「人蔘,大蒜,蜂蜜」是否是現有的項目集。所需的答案是「是」,因爲存在一個單一的ItemsetId,其中包含,這三個ID完全是。請注意,該集合是無序的:對「蜂蜜,大蒜,人蔘」的查詢應具有相同的行爲。

我該怎麼做?

+3

Itemsets只是集合的名稱。除了愚蠢的名字,我沒有看到一個特殊的問題。 – 2012-07-29 12:02:24

+0

我猜你將不得不使用動態SQL(假設你的參數是動態的) – Kane 2012-07-29 12:11:30

回答

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 

這會將所有建議的項目與所有項目集連接起來。然後按每個項目集中的項目進行分組,給出一個關於該項目是否在集合中的標誌。最後,它檢查項目集中的所有項目都在兩者中。

0

聽起來像是你需要找到一個ItemSet是:

  1. 包含所有Item在你的通緝名單
  2. 不含任何其他Item小號

這個例子將返回這樣的項目集的ID(如果存在)。

注:這個解決方案是MySQL,但它應該在SQLite的工作,一旦你改變@variable捲入一些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

相關問題