我有一个数据库(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赞赏。
答案 0 :(得分:2)
您可以尝试使用EXCEPT
SELECT ItemID FROM Table
EXCEPT
SELECT ItemID FROM Table
WHERE
CategoryID <> 12
答案 1 :(得分: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;
答案 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