如何在连接表中选择确切的相关值

时间:2018-03-20 22:11:14

标签: mysql sql

我在执行以下SELECT语句时遇到问题:我只想选择与某些给定articles完全相关的tags

这是我的(简化)架构:

enter image description here

以下是(简化)数据:

enter image description here

我只想选择与articles 89 tags 137 相关的AND
这应仅返回article (ID 3),该tags仅与{{1}} ID 89 137 相关。

我正在考虑用两个查询来做这个,但也许你们其中一个人可以告诉我如何只用一个查询。

THKS!

4 个答案:

答案 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的灵感。