2

我有一个数据库(NexusDB(应该符合 SQL-92)),其中包含 Item 表、一个 Category 表和一个多对多 ItemCategory 表,它只是一对键。如您所料,项目被分配到多个类别。

我希望所有最终用户选择所有项目

物品编号 | 分类号
--------------------------------
01 | 01
01 | 02
01 | 12

02 | 01
02 | 02
02 | 47

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

我希望能够选择分配给类别 X、Y 和 Z 但未分配给类别 P 和 Q 的所有 ItemID。

例如,对于上面的示例数据,假设我想获取分配给类别 01 或 02 但不是 12 的所有项目(产生项目 02 和 03)。类似于以下内容:

SELECT ItemID WHERE (CategoryID IN (01, 02))

...并从该集合中删除 SELECT ItemID WHERE NOT (CategoryID = 12)

这可能是一个非常基本的 SQL 问题,但它现在难倒我。任何帮助 w/b 表示赞赏。

4

4 回答 4

2

你可以试试 EXCEPT

SELECT ItemID FROM Table
EXCEPT
SELECT ItemID FROM Table
WHERE
CategoryID <> 12
于 2008-12-13T09:52:12.023 回答
2

我希望能够选择分配给类别 X、Y 和 Z 但未分配给类别 P 和 Q 的所有 ItemID。

我无法从有关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;
于 2008-12-13T17:50:03.197 回答
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 子句中输入您想要获取的类别。

于 2008-12-13T09:55:46.103 回答
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
     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
于 2008-12-13T14:00:08.157 回答