我在执行以下SELECT
语句时遇到问题:我只想选择与某些给定articles
完全相关的tags
。
这是我的(简化)架构:
以下是(简化)数据:
我只想选择与articles
89 tags
137 相关的AND
。
这应仅返回article (ID 3)
,该tags
仅与{{1}} ID 89 和 137 相关。
我正在考虑用两个查询来做这个,但也许你们其中一个人可以告诉我如何只用一个查询。
THKS!
答案 0 :(得分:2)
根据我的理解,您想要选择仅与标签89 和 137相关的文章ID,而不是其他人?因此,您的样本数据中的ID 3,但不是ID 4和5(仅与其中一个相关)或6(与它们相关,还与其他标签相关)。您可以使用此查询实现此目的:
select a1.article_id
from article_tag a1
where a1.tag_id = 89 and
exists (select * from article_tag a2 where a2.article_id = a1.article_id and a2.tag_id = 137) and
not exists (select * from article_tag a3 where a3.article_id = a1.article_id and a3.tag_id != 137 and a3.tag_id != 89)
答案 1 :(得分:1)
select id as article_id
from article a
where exists
(select 1
from article_tag b
where b.article_id = a.id
and b.tag_id = 89)
and exists
(select 1
from article_tag c
where c.article_id = a.id
and c.tag_id = 137)
and not exists
(select 1
from article_tag d
where d.article_id = a.id
and d.tag_id not in (89,137))
答案 2 :(得分:0)
这是一种简单的方法,假设article_tag
中没有重复:
select article_id
from article_tag
group by article_id
having count(*) = sum( tag_id in (89, 137) );
这正是您想要的。 sum()
可以返回0(如果标签不在文章中),1(如果是),或2(如果两者都是)。 count(*)
表示这些匹配是该文章的唯一标记。
答案 3 :(得分:0)
我带来了另一种解决方案,它可以减少子请求:
SELECT at1.article_id
FROM article_tag at1
INNER JOIN article_tag at2
ON at1.article_id = at2.article_id
WHERE at1.tag_id = 89
AND at2.tag_id = 137
AND not exists (
SELECT *
FROM article_tag at3
WHERE at3.article_id = at1.article_id
AND at3.tag_id != 137
AND at3.tag_id != 89
)
感谢@Bryan Newman和@Nick的灵感。