3

私は3つのテーブルを持っています

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 を持つすべての記事を選択します。
正しい結果:チャンネル c1 に Article1 が 1 つだけあります。

私の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') に存在する結果を除外しないことです。

何か案は?

4

1 に答える 1

2

タイプミスを除いて、クエリは問題ないように見えます。

問題は、この要件に適合しないことです。

例: チャネル a1 を持ち、チャネル a2 を持たないすべての記事を選択します。正しい結果: 両方の記事がチャネル c2 にあるため、空です。

MySQL でサポートされていない Set1 から Set2 操作を差し引いたものが必要なようです。

ただし、次のようなものを使用して回避できます。

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 は次のとおりです。

更新: サブクエリを使用することもできます:

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')
)
于 2013-09-17T09:43:37.273 に答える