比方说,我需要查找所有带有所有三个标签标记的文章:food
,lifestyle
和health
。在MySQL中最有效的方法是什么?我想出了这个解决方案:
select * from articles
where exists (
select * from tags
join article_tag on article_tag.tag_id = tags.id
where article_tag.article_id = articles.id
and tags.tag = 'food'
) and exists (
select * from tags
join article_tag on article_tag.tag_id = tags.id
where article_tag.article_id = articles.id
and tags.tag = 'lifestyle'
) and exists (
select * from tags
join article_tag on article_tag.tag_id = tags.id
where article_tag.article_id = articles.id
and tags.tag = 'health'
)
它工作正常,但是看起来很重复。解决此问题的最有效的查询是什么?
答案 0 :(得分:1)
select a.*
from articles a
join (
select articles.id
from articles
join article_tag on article_tag.article_id = articles.id
join tags on article_tag.tag_id = tags.id
where tags.tag in ('food','lifestyle','health')
group by articles.id
having SUM(CASE WHEN tags.tag = 'food' THEN 1 ELSE 0 END) >= 1
AND SUM(CASE WHEN tags.tag = 'lifestyle' THEN 1 ELSE 0 END) >= 1
AND SUM(CASE WHEN tags.tag = 'health' THEN 1 ELSE 0 END) >= 1) b on a.id = b.id
答案 1 :(得分:0)
您可以改为使用条件聚合:
select a.*
from articles a join
article_tag at
on at.article_id = a.id join
tags t
on at.tag_id = t.id
where t.tag in ('food', 'lifestyle', 'health')
group by a.id
having count(*) = 3;
这有两个合理的假设:
id
是article
中的主键(或至少是唯一键)tag_id
没有重复答案 2 :(得分:0)
这是解决方案:
select a.*
from
articles a
inner join(
select at.article_id
from
article_tag at
inner join tags t
on t.id = at.tag_id
where t.tag in ('food', 'lifestyle', 'health')
group by at.article_id
having count(distinct t.tag) = 3
) at
on at.article_id = a.id
答案 3 :(得分:-1)
select * from articles
where articles.id in (
select article_tag.article_id from tags
join article_tag on article_tag.tag_id = tags.id
where article_tag.article_id = articles.id
and tags.tag in ('food', 'lifestyle', 'health')
having count(*) >= 3
)