我在查询时遇到问题。我已经尝试了子查询,不同的连接和group_concat(),但它们要么不起作用,要么非常缓慢。这可能有点难以解释,但问题出在这里:
我有一个表“item”(约有2000个产品)。我有一个表“标签”(包含大约2000个不同的产品标签)。我有一个表“tagassign”(它将标签连接到项目,大约有200000条记录)。
我正在使用标签来定义产品的特征,例如颜色,兼容性,产品是否特价等等。现在,如果我希望能够显示分配了特定标签的产品,我使用一个简单的查询:
select * from item, tagassign
where item.itemid = tagassign.itemid
and tagassign.tagid = "specialoffer"
问题是,我可能希望看到包含多个标签的项目。例如,我可能只希望看到与Apple iPhone兼容的黑色手机外壳并且是新的。所以我基本上想要查看项目表中的所有记录,其中包含标签“black”和“case”以及“iphone”和“new”。我能让它工作的唯一方法是创建4个别名(select * from item,tagassign,tagassign as t1,tagassign as t2,tagassign as t3等)。在某些情况下,我可能会寻找10或20个不同的标签,并且有很多记录,查询速度非常慢。
我知道我错过了一些明显的东西。有任何想法吗? 谢谢!
答案 0 :(得分:3)
SELECT *
FROM item i
WHERE (
SELECT COUNT(*)
FROM tagassign ta
WHERE ta.tagid IN ('black', 'case', 'iphone', 'new')
AND ta.itemid = i.itemid
) = 4
替换您要搜索的标签的实际数量,而不是4
。
在tagassign (itemid, tagid)
上创建一个唯一索引或主键(按此顺序),以便快速工作。
如果您要搜索大量标签(或很少使用的标签),此查询也可能更快:
SELECT i.*
FROM (
SELECT itemid
FROM tagassign ta
WHERE ta.tagid IN ('black', 'case', 'iphone', 'new')
GROUP BY
itemid
HAVING COUNT(*) = 4
) t
JOIN item i
ON i.itemid = t.itemid
对于此查询,您需要tagassign (tagid, itemid)
上的唯一索引。