SQL问题:排除记录

时间:2008-12-13 09:38:40

标签: sql nexusdb sql-match-all

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

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

的项目

ItemID |类别ID
--------------------------------
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 个答案:

答案 0 :(得分:2)

  

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

我无法在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;

答案 1 :(得分:2)

您可以尝试使用EXCEPT

SELECT ItemID FROM Table
EXCEPT
SELECT ItemID FROM Table
WHERE
CategoryID <> 12

答案 2 :(得分: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子句中加入你想要获得的类别。

答案 3 :(得分: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