SQL问题:排除记录

发布于 2024-07-09 13:45:55 字数 685 浏览 6 评论 0原文

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

我希望所有最终用户选择

ItemID | 的所有项目 类别ID
--------------------------------
01 | 01
01 | 02
01 | 12

02 | 01
02 | 02
02 | 47

03 | 47 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表示赞赏。

I have a database (NexusDB (supposedly SQL-92 compliant)) which contains and Item table, a Category table, and a many-to-many ItemCategory table, which is just a pair of keys. As you might expect, Items are assigned to multiple categories.

I am wanting to all the end user to select all items which are

ItemID | CategoryID
--------------------------------
01 | 01
01 | 02
01 | 12

02 | 01
02 | 02
02 | 47

03 | 01
03 | 02
03 | 14
etc...

I want to be able to select all ItemID's that are assigned to Categories X, Y, and Z but NOT assigned to Categories P and Q.

For the example data above, for instance, say I'd like to grab all Items assigned to Categories 01 or 02 but NOT 12 (yielding Items 02 and 03). Something along the lines of:

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

...and remove from that set SELECT ItemID WHERE NOT (CategoryID = 12)

This is probably a pretty basic SQL question, but it's stumping me at the moment. Any help w/b appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

白龙吟 2024-07-16 13:45:55

你可以尝试使用除了

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

You could try with EXCEPT

SELECT ItemID FROM Table
EXCEPT
SELECT ItemID FROM Table
WHERE
CategoryID <> 12
情深如许 2024-07-16 13:45:55

我希望能够选择全部
分配给的 ItemID
类别 X、Y 和 Z,但 NOT
分配给类别 P 和 Q。

我无法从 NexusDB 文档中确认 SELECT 他们支持子查询,但他们确实支持 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;

I want to be able to select all
ItemID's that are assigned to
Categories X, Y, and Z but NOT
assigned to Categories P and Q.

I can't confirm from the NexusDB documentation on SELECT that they support subqueries, but they do support LEFT OUTER JOIN and GROUP BY. So here's a query that works within these restrictions:

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;
和影子一齐双人舞 2024-07-16 13:45:55
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 子句中输入您想要获取的类别。

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

Of course you need to put in the WHERE clause what categories you want to get.

没有伤那来痛 2024-07-16 13:45:55

对于类别数量较少且已知的简单情况,您可以简单地使用多个联接来检查存在和不存在:

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

For the simple case that you have with a low and known number of categories you can simply use several joins to check for existence and non-existence:

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

For a more general case, given an unknown number of items in the match and don't match lists, you can use the following query. I've used a table variable (available in SQL Server) for each of the lists, but you can use a select against an actual table or a list of variables/parameters as needed. The idea remains the same:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文