2008-12-13 189 views
2

我有一个数据库(NexusDB(据称是SQL-92兼容)),其中包含和Item表,一个Category表和一个多对多的ItemCategory表,它只是一对键。正如您所期望的那样,项目被分配到多个类别。SQL的问题:不包括记录

,我想所有的最终用户选择哪些是

项目ID的所有项目| CategoryID
--------------------------------
01 | 01
01 | 02
01 | 12

02 | 01
02 | 02
02 | 47

03 | 01
03 | 02
03 | 14
等...

我希望能够选择分配给类别X,Y和Z,但没有分配到分类P和Q

对于上面的示例数据的所有项目ID的例如,假设我想抓取分配给类别01或02但不是12的所有项目(产生项目02和03)。沿着线的东西:

SELECT项目ID WHERE(类别ID IN(01,02))

...,并从该组删除选择的ItemID WHERE NOT(类别id = 12)

这可能是这是一个非常基本的SQL问题,但目前它困扰着我。任何帮助W/B赞赏。

+0

谢谢大家!汤姆的回答对我所需要的是完美的,但对我来说都是信息丰富的。很多学习SQL仍然(我相信我会回来w /更多的问题)...感谢您的帮助。 :) – Jamo 2008-12-13 20:30:09

回答

2

您可以尝试与除

SELECT ItemID FROM Table 
EXCEPT 
SELECT ItemID FROM Table 
WHERE 
CategoryID <> 12 
1
SELECT i.ItemID, ic.CategoryID FROM Item AS i 
INNER JOIN ItemCategory ic 
ON i.ItemID = ic.ItemID 
WHERE ic.CategoryId = 1 OR ic.CategoryId = 2 

当然,你需要把WHERE子句你想获得哪些类别英寸

+0

即使它们不在第2类中,这也会得到第1类中的物品。我不认为这是原始海报所需要的。 – 2008-12-13 13:41:38

0

对于你有一个较低的和已知数量的类别,你可以简单地用几个简单的情况下加入到检查存在和不存在:

SELECT 
    ItemID 
FROM 
    Items I 
INNER JOIN ItemCategories IC1 ON IC1.ItemID = I.ItemID AND IC1.CategoryID = '01' 
INNER JOIN ItemCategories IC2 ON IC2.ItemID = I.ItemID AND IC2.CategoryID = '02' 
LEFT OUTER JOIN ItemCategories IC3 ON IC3.ItemID = I.ItemID AND IC3.CategoryID = '12' 
WHERE IC3.ItemID IS NULL 

对于更一般的情况下,给定一个未知匹配中的项目数量与列表不匹配,可以使用以下查询。我已经为每个列表使用了一个表变量(在SQL Server中可用),但是您可以根据需要对实际表或变量/参数列表使用select。这个想法是一样的:

SELECT 
    ItemID 
FROM 
    Items I 
WHERE 
    (
     SELECT COUNT(*) 
     FROM ItemCategories IC1 
     WHERE IC1.ItemID = I.ItemID 
     AND IC.CategoryID IN 
      (SELECT CategoryID FROM @MustHaves) 
    ) = (SELECT COUNT(*) FROM @MustHaves) AND 
     (
     SELECT COUNT(*) 
     FROM ItemCategories IC1 
     WHERE IC1.ItemID = I.ItemID 
     AND IC.CategoryID IN 
      (SELECT COUNT(*) FROM @MustNotHaves) 
    ) = 0 
2

我希望能够选择分配给 分类X,Y和Z但不 分配到分类P和Q

所有 项目ID的

我无法从关于SELECT的NexusDB文档中确认它们支持子查询,但它们确实支持LEFT OUTER JOIN和GROUP BY。所以这里是一个查询,在这些限制内工作:

SELECT i1.ItemID 
FROM ItemCategory i1 
    LEFT OUTER JOIN ItemCategory i2 
    ON (i1.ItemID = i2.ItemID AND i2.CategoryID IN ('P', 'Q')) 
WHERE i1.CategoryID IN ('X', 'Y', 'Z') 
    AND i2.ItemID IS NULL 
GROUP BY i1.ItemID 
HAVING COUNT(i1.CategoryID) = 3; 
+0

不错的方法+1 :) – 2008-12-13 18:09:08