次の例では、 、 、および をトピック ID の代わりに使用x
しy
てz
います。例として何も提供されていません。
JOIN の使用:
SELECT m.*
FROM MESSAGES m
JOIN MESSAGETOPICRELATIONS mtr ON mtr.messageid = m.messageid
JOIN TOPICS tx ON tx.topicid = mtr.topicid
AND tx.topicid = x
JOIN TOPICS ty ON ty.topicid = mtr.topicid
AND ty.topicid = y
JOIN TOPICS tz ON tz.topicid = mtr.topicid
AND tz.topicid = z
GROUP BY/HAVING COUNT(*) の使用:
SELECT m.*
FROM MESSAGES m
JOIN MESSAGETOPICRELATIONS mtr ON mtr.messageid = m.messageid
JOIN TOPICS t ON t.topicid = mtr.topicid
WHERE t.topicid IN (x, y, z)
GROUP BY m.messageid, m.messagetext
HAVING COUNT(*) = 3
2 つのうち、JOIN アプローチの方が安全です。
MESSAGETOPICRELATIONS.TOPICID
GROUP BY/HAVING は、主キーの一部であるか、重複しないように一意のキー制約を持っていることに依存しています。そうしないと、同じトピックの 2 つ以上のインスタンスがメッセージに関連付けられる可能性があります。これは誤検知となります。を使用HAVING COUNT(DISTINCT ...
すると誤検知が解消されますが、サポートはデータベースに依存します。MySQL は 5.1+ でサポートしていますが、4.1 ではサポートしていません。Oracle は、SQL Server でテストするために月曜日まで待たなければならないかもしれません...
TOPICS
テーブルへの結合が不要であるというビルのコメントを調べました。
SELECT m.*
FROM MESSAGES m
JOIN MESSAGETOPICRELATIONS mtr ON mtr.messageid = m.messageid
AND mtr.topicid IN (x, y, z)
IN
...は偽陽性を返します -句で定義された値の少なくとも 1 つに一致する行。と:
SELECT m.*
FROM MESSAGES m
JOIN MESSAGETOPICRELATIONS mtr ON mtr.messageid = m.messageid
AND mtr.topicid = x
AND mtr.topicid = y
AND mtr.topicid = z
...topicid
一度にすべての値を取得することはできないため、何も返しません。