我们说我有这些数据(请注意第三本书中的空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) )
}
答案 0 :(得分:3)
你想要的是LEFT JOIN
而不是INNER JOIN
:
http://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%';