在Mysql中如何进行这个查询呢?

发布于 2024-07-14 17:28:08 字数 779 浏览 6 评论 0原文

我有 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 个主题每行相关,但主题超过 1 的消息有重复行。

那么,你有什么推荐呢?

I have 3 tables, message, subject and message_subject_rel. The idea is to have messages that can relate to a lot of subjects and then do a cross subject search.

Lets say I have a message:

Id: 1, Message: This is a message

2 subjects:

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

And there's 2 message_subject_rel entries that go:

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

If i wanted to search the messages that are related with math, I would do a simple join with the 3 tables and the where clause would be subject = "Math"

But what I don't know how to do, is search for the messages that are related with math AND Science.
If i do a simple join i get tables with something like:

id  message     user_id     created_at  ip  id  message_id  subject_id  id  subject

And if I do a where subject = "Math" and subject = "Science" i wont get any results because each message will only have 1 subject related in each row, but duplicated rows for messages with more than 1 subject.

So, what do you recommend?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

漆黑的白昼 2024-07-21 17:28:08

这与 Filtering from join-table 基本上是相同的问题,

我将调整我的答案这个问题。

JOIN 解决方案:

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 解决方案:

请注意,除非您使用 MySQL,否则您需要在 GROUP BY 子句中列出所有 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');

修改的 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 列。

This is basically the same question as Filtering from join-table

I'll adapt my answer from that question.

JOIN solution:

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 solution:

Note that you need to list all m.* columns in the GROUP BY clause, unless you use 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;

Subquery solution:

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

Modified GROUP BY solution:

Simplifies GROUP BY clause by isolating search in a subquery.

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: There's no reason your message_subject_rel table needs an ID column.

抚你发端 2024-07-21 17:28:08

在 where 子句中进行内部选择。

SELECT FROM [表和连接] WHERE subject = "Math" AND message_id IN (SELECT message_id FROM [表和连接] WHERE subject = "Science")

Do an inner select in your where clause.

SELECT FROM [tables and joins] WHERE subject = "Math" AND message_id IN (SELECT message_id FROM [tables and joins] WHERE subject = "Science")

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文