我有以下查询,该查询使用参考表tag_titles和tags_blogs与其中包含标签的表进行比较,该表称为tag。标签本身保存在t.label列中。
我的问题是有时它count()过多total_matches。通常,在tags_titles和tags_blogs中可以找到引用的标签时。是否有任何方法可以使内部联接互斥,或采用其他解决方案,以使对t.label列的实际匹配计数准确无误?
SELECT b.blog_id AS id, b.title AS title, b.body AS body, COUNT(t.label) AS total_matches, b.creation_time AS creation_time, '1' AS type
FROM tags AS t
INNER JOIN tags_titles AS tt
ON tt.tag_id = t.tag_id
INNER JOIN tags_blogs AS tb
ON tb.tag_id = t.tag_id
INNER JOIN blogs AS b
ON tt.blog_id=b.blog_id OR tb.blog_id=b.blog_id
WHERE t.label IN ($in) AND b.title IS NOT NULL
GROUP BY id, title, body, creation_time, type
您的问题是标题有一个标签列表,博客有一个标签列表,并且每个博客都获得这些标签的笛卡尔积。
解决您的问题的简单方法是使用count(distinct)
:
SELECT b.blog_id AS id, b.title AS title, b.body AS body, COUNT(distinct t.label) AS total_matches,
b.creation_time AS creation_time, '1' AS type
FROM tags AS t
INNER JOIN tags_titles AS tt
ON tt.tag_id = t.tag_id
INNER JOIN tags_blogs AS tb
ON tb.tag_id = t.tag_id
INNER JOIN blogs AS b
ON tt.blog_id=b.blog_id OR tb.blog_id=b.blog_id
WHERE t.label IN ($in) AND b.title IS NOT NULL
GROUP BY id, title, body, creation_time, type;
在更复杂的场景中,有时您需要在联接之前沿单独的维度进行聚合。
您还有另一个问题t.label in ($in)
。这不适用于in。相反,您可以使用:
find_in_set(t.label, $in) > 0;
或在SQL中直接替换列表。前一种方法不使用索引进行过滤。后者将(如果合适的话)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句