Reputation: 1406
I have three tables
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
Now I want to select all Articles that are included in one collection AND excluded in another.
Ex: Select all articles that have Channel a1 AND not Channel a2.
Correct result: Empty since both articles are in Channel c2.
Ex: Select all articles that have Channel a1.
Correct result: Article1 only one in Channel c1.
My SQL looks like this:
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');
The problem is that the result doesn't exclude result that are existing in the c.id NOT IN ('a2').
Any ideas?
Upvotes: 3
Views: 10634
Reputation: 752
Your query looks just fine except for typos.
The problem is it doesn't fit for this requirement:
Ex: Select all articles that have Channel a1 AND not Channel a2. Correct result: Empty since both articles are in Channel c2.
Looks like you want Set1 minus Set2 operation which is not supported by MySQL.
But you can workaround it using something like this:
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;
Here is SQL Fiddle for the case
UPDATED: You can also go on with subquery:
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')
)
Upvotes: 2