【问题标题】:Multiple Joins Working Independantly But Not Together多个联接独立工作但不一起工作
【发布时间】:2017-01-27 02:22:25
【问题描述】:

我试图从名为 book_info 和 copy_info 的表中获取行信息的结果,然后(如果它们存在)来自名为 publisher 的表(其外键在 copy_info 中),并且(如果它们存在)结果通过名为 books_genres 的连接表从表名流派中获取。下面,$safe_copy_id 是在 php 语句中定义的,为了示例,我将其保留。

这行得通:

SELECT * FROM book_info, copy_info
LEFT OUTER JOIN publisher ON copy_info.publisher_id = publisher.publisher_id
WHERE book_info.book_id = copy_info.book_id
AND copy_info.copy_id = $safe_copy_id LIMIT 1

这很有效:

SELECT * FROM book_info, copy_info, books_genres
LEFT OUTER JOIN genre ON books_genres.genre_id = genre.genre_id
WHERE book_info.book_id = copy_info.book_id
AND copy_info.copy_id = $safe_copy_id LIMIT 1

但我真正想做的是:

SELECT * FROM book_info, copy_info, books_genres
LEFT OUTER JOIN publisher ON copy_info.publisher_id = publisher.publisher_id
LEFT OUTER JOIN genre ON books_genres.genre_id = genre.genre_id
WHERE book_info.book_id = copy_info.book_id
AND copy_info.copy_id = $safe_copy_id LIMIT 1

我应该在这里嵌套一些东西吗?不知道如何前进,并希望有任何见解。

【问题讨论】:

  • 简单规则:从不FROM 子句中使用逗号。 始终使用正确、明确的JOIN 语法。这可能会解决您的问题。
  • @GordonLinoff 我从 FROM 子句中删除了逗号。我不确定这是否是您的意思,但我从每个连接子句中删除了“LEFT OUTER”,只说 JOIN。不幸的是,这不起作用。
  • 我不确定第二个查询是如何工作的。 books_genresbook_infocopy_info 没有连接条件。您是否正在寻找来自book_genres 的笛卡尔积?如果您为所有表格提供 2 行并基于此提供预期输出,这将有所帮助。
  • @Ustav 对不起,我现在意识到第二个查询只返回流派表中的第一个结果,无论 copy_id 是什么。我将努力编辑它以包含一个连接条件。我的错。

标签: sql join outer-join


【解决方案1】:

正确使用JOIN

SELECT *
FROM book_info bi JOIN
     copy_info ci
     ON bi.book_id = ci.book_id JOIN
     publisher p
     ON ci.publisher_id = p.publisher_id JOIN
     books_genres bg
     ON bg.book_id = bi.book_id JOIN  -- your question doesn't specify the JOIN condition here
     genre g
     ON bg.genre_id = g.genre_id
WHERE ci.copy_id = $safe_copy_id
LIMIT 1;

您缺少对book_genres 的连接。也许它链接到book_info

另外,我认为没有理由为查询使用外连接。我怀疑所有表都有有效的外键关系。

【讨论】:

  • 您是正确的,books_genres 与图书信息相关联,我试图运行这个确切的查询,并将 ?? 替换为正确的链接,但仍然失败。不过,感谢您纠正我的语法。
  • 我使用了外连接,因为不是每个 copy_id 都会有从发布者或流派表返回的行。我不确定具体原因,但如果我只使用 JOIN,它会返回 null,而如果我使用外连接,它只会为特定列返回 null(例如,genre_id)。这是我对我的经验的最好解释,如果这是正确使用外连接,我不会。
  • @KaariLandry 。 . .似乎有道理。只需将所有JOINs 替换为LEFT JOINs。
【解决方案2】:

感谢 Gordon Linoff 和 Utsav 指出我没有加入 book_genres。这是实际工作的查询:

 SELECT * FROM
book_info bi JOIN copy_info ci
 ON bi.book_id = ci.book_id
 LEFT OUTER JOIN publisher p
 ON ci.publisher_id = p.publisher_id
 LEFT OUTER JOIN books_genres bg
 ON bg.book_id = bi.book_id
 LEFT OUTER JOIN genre g
 ON bg.genre_id = g.genre_id
WHERE ci.copy_id = $safe_copy_id
LIMIT 1;

【讨论】:

    猜你喜欢
    • 2020-01-20
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-14
    • 2018-07-26
    • 1970-01-01
    相关资源
    最近更新 更多