【问题标题】:MySQL -- joining then joining then joining againMySQL - 加入然后加入然后再次加入
【发布时间】:2009-06-14 03:25:13
【问题描述】:

MySQL 设置:一步一步。

节目 -> 链接到 --> 演讲者(通过 program_id)

此时,我可以轻松查询所有数据:

SELECT * 
FROM programs 
JOIN speakers on programs.program_id = speakers.program_id

简单又好用。

对我来说,诀窍就是这个。我的扬声器表还链接到第三个表“书籍”。因此,在“speakers”表中,我有“book_id”,而在“books”表中,book_id 与名称相关联。

我已经试过了(包括你会注意到的 WHERE):

SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
LIMIT 5

没有结果。

我的问题:

  1. 我做错了什么?
  2. 进行此查询的最有效方法是什么?

基本上,我想取回所有程序数据和书籍数据,但不是 book_id,而是需要它作为书籍名称(来自第三个表)返回。

提前感谢您的帮助。

更新:
(而不是提出一个全新的问题)

左连接对我有用。但是,我有一个新问题。多本书可以分配给一个扬声器。

使用左连接,返回两行!!我需要添加什么才能仅返回一行,但将两本书分开。

【问题讨论】:

  • 该查询对我来说看起来不错,而且这几乎是您尝试做的事情的常用方式。您确定没有其他问题(例如,您是否尝试过消除 WHERE 子句,您确定数据库中的数据应该为此返回匹配项等)?

标签: mysql join


【解决方案1】:

books 表是否有可能没有任何与 speaker.book_id 匹配的列?

尝试使用左连接,即使书中没有匹配项,它仍会返回节目/演讲者组合。

SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
LEFT JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
LIMIT 5

顺便说一句,您能否发布所有相关表的表架构,以及您希望获得的确切输出(或合理表示)?

编辑:对 op 作者评论的回应

您可以使用 group by 和 group_concat 将所有书籍放在一行。

例如

SELECT speakers.speaker_id, 
       speakers.speaker_name, 
       programs.program_id, 
       programs.program_name,
       group_concat(books.book_name)
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
LEFT JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
GROUP BY speakers.id
LIMIT 5

注意:由于我不知道确切的列名,这些可能是关闭的

【讨论】:

  • LEFT OUTER JOIN 相当于 MySQL 中的 JOIN
  • 嗯,JOIN 与 MySQL 5.0 中的 INNER (CROSS) JOIN 相同。
  • 有什么文档支持吗? dev.mysql.com/doc/refman/5.0/en/join.html 表示内连接相当于逗号,逗号可以用JOIN代替。 A=B=C。内连接 = 连接
  • 哦!你是对的。我在想 LEFT JOIN 等同于 LEFT OUTER JOIN。对不起。
  • 谢谢大家!还有一个问题(参见上面的“更新”)。可以将多本书分配给一个演讲者——因此,新查询为单个 program_id 返回两行。关于如何使结果成为单行并使“book_name”列唯一的任何想法?
【解决方案2】:

这通常很有效。您所做的某种假设是不正确的。你的演讲者有分配书籍吗?如果他们没有最后一个JOIN 应该是LEFT JOIN

这种查询通常非常有效,因为您几乎可以肯定将主键作为索引。主要问题是您的索引是否覆盖(如果您不使用SELECT *,而是只选择您需要的列,则更有可能发生这种情况)。

【讨论】:

    猜你喜欢
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    相关资源
    最近更新 更多