これらのテーブルがあります: Products、Articles、Product_Articles
たとえば、product_ids は次のとおりです: p1、p2 article_ids は: a1、a2、a3 product_articles は次のとおりです。
- (p1,a1)
- (p1,a2)
- (p2,a1)
- (p2,a1)
- (p2,a2)
- (p2,a3)
a1、a2、それ以下でもそれ以上でもない、product_id を照会する方法は?
更新済み
SELECT p.*
FROM products p JOIN
(
SELECT product_id
FROM product_articles
GROUP BY product_id
HAVING COUNT(*) = SUM(CASE WHEN article_id IN (1, 2) THEN 1 ELSE 0 END)
AND SUM(CASE WHEN article_id IN (1, 2) THEN 1 ELSE 0 END) = 2
) q ON p.product_id = q.product_id
また
SELECT p.*
FROM products p JOIN
(
SELECT product_id, COUNT(*) a_count
FROM product_articles
WHERE article_id IN (1, 2)
GROUP BY product_id
HAVING COUNT(*) = 2
) a ON p.product_id = a.product_id JOIN
(
SELECT product_id, COUNT(*) total_count
FROM product_articles
GROUP BY product_id
) b ON p.product_id = b.product_id
WHERE a.a_count = b.total_count
これは両方のクエリのSQLFiddleデモです
これは、「set-within-sets」サブクエリの例です。ロジックの句で集計を使用することをお勧めしhaving
ます。これが関係を表現する最も一般的な方法だからです。
where
アイデアは、ステートメントを使用するのと同様の方法で、製品 (この場合) 内の記事の外観をカウントできるということです。コードはもう少し複雑ですが、柔軟性があります。あなたの場合、これは次のようになります。
select pa.product_id
from product_articles pa
group by pa.product_id
having sum(case when pa.article_id = 'a1' then 1 else 0 end) > 0 and
sum(case when pa.article_id = 'a2' then 1 else 0 end) > 0 and
sum(case when pa.article_id not in ('a1', 'a2') then 1 else 0 end) = 0;
最初の 2 つの句は、2 つの記事の出現回数をカウントし、それぞれに少なくとも 1 回は出現するようにします。最後は、これら 2 つの記事がない行の数をカウントし、何もないようにします。
これがより多くの記事に簡単に一般化されることがわかります。または、「a1」と「a2」はあるが「a3」がないクエリ。または、4 つのうち 3 つの特定の記事がある場合などです。