1

我有 3 个表格、消息、主题和message_subject_rel. 这个想法是让消息与很多主题相关,然后进行跨主题搜索。

假设我有一条消息:

Id: 1, Message: This is a message

2个科目:

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

并且有 2message_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子句中列出所有 m.* 列,除非您使用 MySQL。

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');

修改后的 GROUP BY 解决方案:

通过隔离子查询中的搜索来简化 GROUP BY 子句。

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 [tables and joins] WHERE subject = "Math" AND message_id IN (SELECT message_id FROM [tables and joins] WHERE subject = "Science")

于 2009-03-16T23:11:57.823 回答