【问题标题】:How to do this query in Mysql?如何在 Mysql 中进行此查询?
【发布时间】:2010-10-13 17:47:56
【问题描述】:

我有 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 个的消息会出现重复行。

那么,你有什么推荐的呢?

【问题讨论】:

    标签: mysql sql-match-all


    【解决方案1】:

    这和Filtering from join-table基本是同一个问题

    我会根据这个问题调整我的答案。

    加入解决方案:

    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 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 列。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 这可行,但会有很多主题的消息,为此我想避免它,但让我们看看会发生什么
      猜你喜欢
      • 2010-10-07
      • 1970-01-01
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多