MySQL选择ID,它出现在具有列的多个特定值的不同行上

fli*_*ker 9 mysql relational-division

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

+-----------------------+
| item_id | category_id |
+-----------------------+
|   1     |    200      |
|   1     |    201      |
|   1     |    202      |
|   2     |    201      |
|   2     |    202      |
|   3     |    202      |
|   3     |    203      |
|   4     |    201      |
|   4     |    207      |
+-----------------------+
Run Code Online (Sandbox Code Playgroud)

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

我最初的SQL语句是这样的

SELECT * FROM item_category WHERE category_id = 201 AND category_id = 202;
Run Code Online (Sandbox Code Playgroud)

但显然这不起作用.

SELECT * FROM item_category WHERE category_id = 201 OR category_id = 202;
Run Code Online (Sandbox Code Playgroud)

上述查询也不起作用,因为它也会返回第4项和第3项.

那么我怎样才能选择至少必须属于两个类别的项目呢?

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

谢谢您的帮助.

Bil*_*win 9

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
Run Code Online (Sandbox Code Playgroud)

当您想要搜索三个,四个,五个或更多值时,此技术很难扩展,因为它需要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
Run Code Online (Sandbox Code Playgroud)

这两种技术都没问题,并且在不同情况下工作得更好.