1

メッセージ、件名、および の 3 つのテーブルがありますmessage_subject_rel。アイデアは、多くの件名に関連するメッセージを作成してから、件名を横断して検索することです。

メッセージがあるとしましょう:

Id: 1, Message: This is a message

2科目:

Id:1, Subject: Math
Id:2, Subject: Science

そして、次の 2 つのmessage_subject_relエントリがあります。

Id: 1, message_id: 1, subject_id: 1
Id: 2, message_id: 1, subject_id: 2

数学に関連するメッセージを検索したい場合は、3 つのテーブルを単純に結合し、where 句を subject = "Math" にします。

しかし、どうすればよいかわかりません。数学と科学に関連するメッセージを検索することです。単純な結合を行うと、次のようなテーブルが得られます。

id  message     user_id     created_at  ip  id  message_id  subject_id  id  subject

また、where subject = "Math" and subject = "Science"各メッセージには各行に関連する件名が1つしかないため、結果が得られませんが、複数の件名を持つメッセージの行が重複します。

それで、あなたは何をお勧めしますか?

4

2 に答える 2

3

これは基本的に、結合テーブルからのフィルタリングと同じ質問です。

私はその質問から私の答えを適応させます。

ソリューションに参加する:

SELECT m.*
FROM messages m
 JOIN message_subject_rel ms1 ON (m.id = ms1.message_id)
 JOIN subjects s1 ON (ms1.subject_id = s1.id AND s1.subject = 'Math')
 JOIN message_subject_rel ms2 ON (m.id = ms1.message_id)
 JOIN subjects s2 ON (ms2.subject_id = s2.id AND s2.subject = 'Science');

GROUP BYソリューション:

GROUP BYMySQLを使用しない限り、句内のすべてのm。*列をリストする必要があることに注意してください。

SELECT m.*
FROM messages m 
 JOIN message_subject_rel ms ON (m.id = ms.message_id)
 JOIN subjects s ON (ms.subject_id = s.id)
WHERE s.subject IN ('Math', 'Science'))
GROUP BY m.id, ...
HAVING COUNT(*) = 2;

サブクエリソリューション:

SELECT m.*
FROM messages m
WHERE m.id = ANY (SELECT message_id 
                  FROM message_subject_rel ms JOIN subjects s 
                    ON (ms.subject_id = s.id) 
                  WHERE s.subject = 'Math')
  AND m.id = ANY (SELECT message_id 
                  FROM message_subject_rel ms JOIN subjects s 
                    ON (ms.subject_id = s.id) 
                  WHERE s.subject = 'Science');

変更されたGROUPBYソリューション:

サブクエリで検索を分離することにより、GROUPBY句を簡略化します。

SELECT m.*
FROM messages m
WHERE m.id IN (
  SELECT ms.message_id FROM message_subject_rel ms JOIN subjects s
    ON (ms.subject_id = s.id)
  WHERE s.subject IN ('Math', 'Science'))
  GROUP BY ms.message_id HAVING COUNT(*) = 2
);

PS:message_subject_relテーブルにID列が必要な理由はありません。

于 2009-03-16T23:27:21.547 に答える
0

where句で内部選択を行います。

SELECT FROM [テーブルと結合] WHERE subject = "Math" AND message_id IN (SELECT message_id FROM [テーブルと結合] WHERE subject = "科学")

于 2009-03-16T23:11:57.823 に答える