SELECT WHERE IN()AND NOT IN()

时间:2013-09-17 08:47:10

标签: mysql sql

我有三张桌子

Articles        Channels        ArticlesChannels
pk    id        pk    id        pk    articlePk    channelPk
1     a1        1     c1        1     1            1
2     a2        2     c2        2     1            2
                                3     2            2

现在,我想选择一个集合中包含的所有文章,并在另一个集合中排除。

例如:选择所有包含频道a1但不包含频道a2的文章 正确结果清空,因为这两篇文章都在渠道c2中。

例如:选择所有包含频道a1的文章 正确的结果:第1条只有一条在渠道c1。

我的SQL看起来像这样:

SELECT a.id 
FROM articles a, channels c, articlechannels ac 
WHERE a.pk=ac.articlePk 
AND ac.channelPk = c.pk 
AND c.id IN ('a1') 
AND c.id NOT IN ('a2');

问题是结果不排除c.id NOT IN('a2')中存在的结果。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

除了拼写错误,你的查询看起来很好。

问题是它不适合这个要求:

  

例如:选择所有包含频道a1而非频道a2的文章。   正确的结果:因为两篇文章都在频道c2中而空。

看起来你想要Set1减去Set2操作,这是MySQL不支持的。

但您可以使用以下内容解决问题:

select a.id, sum(case when c.id = 'c1' then 1 else 0 end) as c1, sum(case when c.id = 'c2' then 1 else 0 end) as c2
from Articles a
inner join ArticleChannels ac
on a.pk = ac.articlePk
inner join Channels c
on c.pk = ac.channelPk
group by a.id
having c1 = 1 and c2 = 0; 

这是SQL Fiddle for the case

更新: 您还可以继续使用子查询:

SELECT a.id 
FROM articles a, channels c, articlechannels ac 
WHERE a.pk=ac.articlePk 
AND ac.channelPk = c.pk 
AND c.id IN ('a1') 
AND a.id NOT IN (
  SELECT a.id 
  FROM articles a, channels c, articlechannels ac 
  WHERE a.pk=ac.articlePk 
  AND ac.channelPk = c.pk 
  AND c.id NOT IN ('a2')
)