Rails - JOIN 子句不包含具有空外键的行

hrs*_*ono 0 mysql ruby-on-rails squeel

假设我有这个数据(注意author_id第三本书中的空值):

     Authors
-------------------------
  id  |  name
-------------------------
  1   |  Susan Collins
  2   |  Steven Meyer
-------------------------

   Books
--------------------------------------
 id  |  author_id  |  title
--------------------------------------
 1   |      1      |  Hunger Games
 2   |      2      |  Twilight
 3   |     nil     |  Games of Throne
--------------------------------------
Run Code Online (Sandbox Code Playgroud)

我有一个书籍搜索栏。我希望它可以通过书名和作者姓名进行搜索。

例如,当我搜索“苏珊”时。它将返回标题为“Susan”或作者名称为“Susan”之类的书籍。

问题是:当我搜索“游戏”时,它只返回“饥饿游戏”。它没有选择“权力的游戏”,因为它author_id是空的。

我在这里制作了SQLFiddle

这是从我的 Rails 代码生成的 SQL:

SELECT books.* FROM books
  INNER JOIN authors ON authors.id = books.author_id
  WHERE (
    ( LOWER(books.title) LIKE LOWER("%game%") )
    OR
    ( LOWER(authors.name) LIKE LOWER("%game%") )
)
Run Code Online (Sandbox Code Playgroud)

结果只返回1行:“饥饿游戏”。没有“权力的游戏”。

有没有办法包含带有空外键的行?

我将接受 SQL 查询作为答案,我将尝试自己找出 Rails 代码。

谢谢

[编辑]

这是生成 SQL 的 Rails 代码:(我使用Squeel gem)

search = "%#{params[:search]}%" # the query is taken from param

Books.joins(:author).where {
  ( lower(title) =~ lower(search) ) |
  ( lower(author.name) =~ lower(search) )
}
Run Code Online (Sandbox Code Playgroud)

Syl*_*Syl 6

你想要的是一个LEFT JOIN而不是一个INNER JOINhttp : //blog.codinghorror.com/a-visual-explanation-of-sql-joins/

将 Sql Fiddle 中的 left 替换为 inner ,您将获得有作者和没有作者的书籍。

在轨道你可以有一个左更换加入joinsincludes。因为它保留了第一个表中没有关系的数据,所以当你想急切加载关系时经常使用它来防止 N+1 查询问题。

  • 我认为该特定资源在 SO (http://meta.stackexchange.com/questions/87678/discouraging-w3schools-as-a-resource) 中相当不受欢迎 (2认同)