假设我有这张桌子:
item_id tag_id
------- ------
1 1
1 2
2 2
2 3
正如您可能想象的那样,这是一张表,其中我引用了一些属于它们的项目和标签。一个项目可以有多个标签,并且可以为多个项目选择一个标签。
假设我还有一个特定的标签集合(例如 tag_id = 50、73 和 119)和一个带有 id 的“项目”表(由 引用item_id
)。
是否有一个 有效的查询给我:
- 带有这些标签的项目数
- 物品本身?
我试过的
SELECT COUNT(*) FROM
(
SELECT COUNT(*) AS c FROM items_tags it JOIN items i ON i.id = it.item_id
WHERE (tag_id=7 OR tag_id=95 OR tag_id=150) AND `status`='active'
GROUP BY item_id
) t1 WHERE c=3 <-- c= number of tags
我可以同时获得这两个结果,但查询效率非常低(似乎)。经过 EXPLAIN 检查后,我想摆脱 OR 给出的“范围”。
细化我的问题:问题是我得到了一个写得很糟糕的 PHP 框架,它通过各种标签 ID 迭代了 900 多次。假设您有一个或多个固定 ID(选定的标签),它遍历所有 900 多个标签,以查找具有给定标签的共同项目的出现次数加上迭代的一个(这是一个细化搜索,仅显示具有所有给定标签加一的元素)。
给定的代码是这样工作的:我选择一个或多个标签,它们的 ID 进入查询字符串。假设我选择了标签 54 和 77。代码必须找到同时具有标签 54 和 77 的项目的每个项目 ID 并一一列出:我们获得“带有选定标签的项目”列表。
然后,它提供了优化搜索的选项,奇怪的部分出现了:PHP 代码循环遍历所有 900 多个标签,并且对于每次迭代,它需要一个标签,并计算有多少项目具有所有标签 54、77和迭代中的那个。如果计数 > 0,它会显示带有计数编号的标签名称,过滤掉其项目与所选标签没有任何链接的每个标签。
以不那么“密集”的方式实现相同的结果会很好。