我目前使用以下完美运行的查询:
SELECT * FROM `items` WHERE `id` IN
(SELECT `item_id` FROM `categories_items`
WHERE `category_id` IN (1, 2) GROUP BY `item_id`
HAVING COUNT(`item_id`) = 2);
选择所有选定(复选框)类别中的所有项目。
问题在于,大多数商品属于多个类别,有些商品只有两个类别,当我只检查这两个商品时,我仍然会得到数百个商品的清单,这使得几乎无法找到几个类别。
我的第一个想法是在查询中的某处添加一个ORDER BY "number_of_total_categories_that_the_selected_item_is_in" ASC
,但由于我甚至得到了当前的帮助,并且可能会有很多计算/子查询才能工作,我想到了items
表格中的额外列,用于保存其所在类别的数量!
如果没有,我能想到的就是在需要的时候手动更新category_count
中的items
列。
编辑:Table field that holds row count from another table看起来很有趣,但我不知道它是否适用于MySQL。
答案 0 :(得分:1)
您想使用join
而不是in
。以下查询筛选仅包含所需两个类别的项目。它还计算了可用于order by
:
SELECT i.*
FROM `items` i JOIN
(SELECT `item_id`, COUNT(*) as cnt
FROM `categories_items`
WHERE `category_id` IN (1, 2)
GROUP BY `item_id`
HAVING COUNT(DISTINCT CASE WHEN category_id IN (1, 2) THEN category_id END) = 2
) c
ON i.id = c.item_id
ORDER BY cnt ASC;
编辑:
如果您想计算所有类别,那么请删除where
。它并没有真正做任何事情:
SELECT i.*
FROM `items` i JOIN
(SELECT `item_id`, COUNT(*) as cnt
FROM `categories_items`
GROUP BY `item_id`
HAVING COUNT(DISTINCT CASE WHEN category_id IN (1, 2) THEN category_id END) = 2
) c
ON i.id = c.item_id
ORDER BY cnt ASC;