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

时间:2014-11-04 09:56:02

标签: 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
--------------------------------------

我有一个书籍搜索栏。我希望它可以通过Book的标题和作者的名字进行搜索。

例如,当我搜索" Susan"。它将归还书籍的标题为" Susan"或者像#34;苏珊"。

这样的名字

问题是:当我搜索"游戏"时,它只返回"饥饿游戏"。它没有选择"游戏王座"因为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%") )
)

结果只返回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) )
}

2 个答案:

答案 0 :(得分:3)

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

在你的Sql Fiddle中用内部替换,你将得到有或没有作者的书。

在导轨中,您可以通过joins替换includes来实现左连接。因为它保持第一个表中没有关系的数据,所以当你想要加载关系以防止N + 1查询问题时,通常会使用它。

答案 1 :(得分:0)

也许这就是你所追求的......

SELECT b.* 
  FROM books b
  LEFT
  JOIN authors a
    ON a.id = b.author_id
   AND a.name LIKE '%game%'
 WHERE b.title LIKE '%game%';