提问人:scms 提问时间:7/13/2023 最后编辑:forpasscms 更新时间:7/14/2023 访问量:55
联接到多个类别的项的 SQL 查询
SQL query for items joined to multiple categories
问:
我有这 2 个表、内容项和一个类别的联接表。我只需要一个查询来选择多个类别中的项目(在所有类别中,而不是在任何类别中)。
-- content items
CREATE TABLE `items` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
[...]
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- a join table to a categories table
CREATE TABLE `item_categories` (
`item_id` bigint(20) DEFAULT NULL,
`category_id` bigint(20) DEFAULT NULL,
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
下面是一个查询,用于在连接表中选择两个类别中的条目:
SELECT `item_categories`.* FROM `item_categories`
WHERE `item_categories`.`category_id` IN (11811, 11911)
现在将其与项目表连接起来,可以让我获得任何类别中的项目。简单:
SELECT DISTINCT `items`.* FROM `items`
INNER JOIN `item_categories` ON `item_categories`.`item_id` = `items`.`id`
WHERE `item_categories`.`category_id` IN (11811, 11911)
这有点傻,是的,但是尝试使用 AND(每次 0 个结果):
SELECT DISTINCT `items`.* FROM `items`
INNER JOIN `item_categories` ON `item_categories`.`item_id` = `items`.`id`
WHERE `item_categories`.`category_id` = 11811
AND `item_categories`.`category_id` = 11911
这是我最接近的一次。这似乎过于复杂,一种手动连接,每个类别都有一个:WHERE ID IN
SELECT DISTINCT `items`.* FROM `items`
WHERE ID IN (
SELECT `item_categories`.item_id FROM `item_categories`
WHERE `item_categories`.`category_id` = 11811
)
AND ID IN (
SELECT `item_categories`.item_id FROM `item_categories`
WHERE `item_categories`.`category_id` = 11911
)
有没有更好(更简单)的方法来实现这一目标?
我认为必须有一种方法可以在自加入或分组的联接上设置条件,以便在所有类别中仅选择item_categories。
答:
-1赞
forpas
7/13/2023
#1
使用 aggregation in 获取属于所有类别的 s:item_categories
item_id
SELECT *
FROM items
WHERE id IN (
SELECT item_id
FROM item_categories
WHERE category_id IN (11811, 11911)
GROUP BY item_id
HAVING COUNT(DISTINCT category_id) = 2 -- the number of categories
);
我在定义中没有看到 和 组合的任何唯一约束。
如果有,您可以从该条款中删除。item_categories
item_id
category_id
DISTINCT
HAVING
评论