【问题标题】:MySQL LEFT JOIN issue with three WHERE statementsMySQL LEFT JOIN 问题与三个 WHERE 语句
【发布时间】:2010-04-06 21:06:38
【问题描述】:

我正在为自己构建一个带有标签过滤功能的笔记应用程序,但在尝试使用标签抓取笔记时遇到问题。标签过滤器需要使用 AND 而不是 IN,因为它有助于更​​好地缩小我要查找的范围。

我的表是这样配置的:

+ notes          note_id  |  note_title  |  note_uid

+ tags           tag_id   |  tag_title

+ notes_tags     nt_id    |  nt_note_id  |  nt_tag_id

notes_tags 表跟踪所有笔记的标签。

我不担心返回任何关于标签的信息,所以这里有一个示例 LEFT JOIN,我目前正在使用仅获取带有 只有 1 个标签的笔记。 p>

SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN (1) AND nt_tag_id = 10

这个查询运行完美,它抓取了带有那个单个标签的所有笔记。但是,我在使用这样的查询“精确定位”我的笔记时遇到了问题:

SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN (1) AND nt_tag_id = 10 AND nt_tag_id = 11

我在语法上做错了什么?

【问题讨论】:

标签: php mysql left-join where-clause


【解决方案1】:

假设您要识别具有相关 notes_tags 记录且 nt_tag_ids 为 10 且 nt_tag_ids 为 11 的笔记,那么外连接只会使 DBMS 工作比它需要的更难。

这似乎是最明显的解决方案:

SELECT * FROM notes n
WHERE EXISTS (SELECT 1 FROM notes_tags nt
   WHERE n.note_id=nt.nt_note_id
   AND nt.nt_tag_id=10)
AND EXISTS (SELECT 1 FROM notes_tags nt2
   WHERE n.note_id=nt2.nt_note_id
   AND nt2.nt_tag_id=11);

另一种方法是:

SELECT n.*, COUNT(*) 
FROM notes n,
notes_tags nt
WHERE n.note_id-nt.nt_note_id
AND nt.nt_tag_id IN (10,11)
GROUP BY .... /* need to add these */
HAVING COUNT(*)=2;

注意,这假定它们是 notes_tags 表中 nt_note_id 和 nt_tag_id 的唯一约束。

但以上都只会返回notes表中的数据。如果需要从MN分解表中提取对应的行:

SELECT *
FROM notes n,
notes_tags nt,
notes_tags nt2
WHERE n.note_id=nt.nt_note_id
AND n.note_id=nt2.note_id
AND nt.nt_note_id=nt2.nt_note_id /* can help the optimizer come up with a faster query */
AND nt.nt_tag_id=10
AND nt2.nt_tag_id=11

您可能希望为输出列添加别名,以便更轻松地解析响应。

【讨论】:

    【解决方案2】:

    这将只返回 tag_id 为 10 和 11 的笔记。

    SELECT notes.*
    FROM notes
    INNER JOIN notes_tags a ON notes.note_id = a.nt_note_id
                            AND a.nt_tag_id = 10
    INNER JOIN notes_tags b ON notes.note_id = b.nt_note_id
                            AND b.nt_tag_id = 11
    

    【讨论】:

      【解决方案3】:

      nt_tag_id = 10 AND nt_tag_id = 11 这将始终返回 false

      改用nt_tag_id in (10,11)

      如果你需要两个标签,下面有答案,加入标签表两次

      【讨论】:

      • 如果他想要在 10 11中的音符,则使用 IN (10, 11) 会起作用,但如果他想要同时在 10 11,取决于他的目标。
      • 我希望我猜对了一个字段不能同时等于 10 和 11
      【解决方案4】:

      您在 where 子句中使用 'AND' 而不是使用 'OR',如下所示:

      SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN ( 1 ) AND (nt_tag_id = 10 OR nt_tag_id = 11)
      

      如果要添加更多nt_tag_id,也可以这样使用IN。

      SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN ( 1 ) AND nt_tag_id IN (10, 11)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-28
        • 1970-01-01
        • 2011-07-06
        • 2021-02-15
        • 2010-09-27
        • 2014-05-25
        • 1970-01-01
        相关资源
        最近更新 更多