9

我正在尝试从满足同一字段的两个或多个值的关联表中选择项目,这听起来令人困惑,让我解释一下。

+-----------------------+
| item_id | category_id |
+-----------------------+
|   1     |    200      |
|   1     |    201      |
|   1     |    202      |
|   2     |    201      |
|   2     |    202      |
|   3     |    202      |
|   3     |    203      |
|   4     |    201      |
|   4     |    207      |
+-----------------------+

在表格中,我希望能够只选择我通过的类别中的项目。因此,例如,如果我传递 201 和 202 的类别 ID,我只想要两个类别中的项目(它们可以有其他类别,但至少需要在我查询的类别中),所以在这种情况下,我只想要项目 1 和 2,因为它们是唯一属于 201 和 202 类的项目。

我最初的 SQL 语句类似于

SELECT * FROM item_category WHERE category_id = 201 AND category_id = 202;

但显然那是行不通的。

SELECT * FROM item_category WHERE category_id = 201 OR category_id = 202;

上面的查询也不起作用,因为它也会返回项目 4 和 3。

那么我将如何只选择必须至少同时属于这两个类别的项目呢?

请记住,我可能会传递超过 2 个类别 ID。

感谢您的帮助。

4

5 回答 5

11

您在 WHERE 子句中的表达式适用于连接结果集中的单行。这就是为什么WHERE category_id = 201 AND category_id = 202不起作用 - 因为它不能是单行上的两个值。

因此,您需要某种方法将表中的两行连接到结果集中的一行中。您可以通过自加入来做到这一点:

SELECT c1.item_id
FROM item_category AS c1
INNER JOIN item_category AS c2 ON c1.item_id = c2.item_id
WHERE c1.category_id = 201 AND c2.category_id = 202

当您要搜索三个、四个、五个或更多值时,这种技术很难扩大规模,因为它需要N-1 个连接来匹配N个值。

所以另一种方法是使用 GROUP BY:

SELECT c.item_id, COUNT(*) AS cat_count
FROM item_category AS c
WHERE c.category_id IN (201,202)
GROUP BY c.item_id
HAVING cat_count = 2

这两种技术都可以,并且在不同的情况下效果更好。

于 2011-09-13T19:04:22.360 回答
0

使用 JOIN 或 GROUP BY:

SELECT category_id, fieldhere, anotherfield
FROM item_category
WHERE category_id in (201,202)
GROUP BY category_id
HAVING count(category_id) = 2
于 2011-09-13T19:03:12.223 回答
0

假设每个 item_id、category_id 都是唯一的,

select *, count(item_id) as c from item_category
where category_id in (201, 202)
group by item_id
having c = 2;

将 c = 2 替换为 c =(类别计数)

于 2011-09-13T19:03:37.790 回答
0

我现在没有时间提供确切的查询,但尝试这样的事情:

select item_category.* from 
item_category ,  item_category ic1, item_category ic2 where 
ic1.category_id = 201 and 
ic2.category_id = 202 and 
ic1.item_id = ic2.item_id and 
item_category.item_id = ic1.item_id and 
item_category.item_id = ic2.item_id;

也许条件是错误的,但你可以尝试这种方式。

于 2011-09-13T19:06:42.130 回答
-2

你可以试试:

SELECT * FROM item_category WHERE category_id IN (201, 202, ...)

(或者,正如评论所说......你可能不会。)

于 2011-09-13T19:01:06.377 回答