2014-11-04 54 views
0

比方說,我有這樣的數據(請注意在第三本書空author_id):導軌 - JOIN子句不包括一行空外鍵

 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 
-------------------------------------- 

我有一個圖書搜索欄。我希望它可以通過書的標題和作者的名字進行搜索。

例如,當我搜索「蘇珊」。它將返回書名稱爲「蘇珊」或書名如「蘇珊」。

問題是:當我搜索「遊戲」時,它只返回「飢餓遊戲」。它不會選擇「王座遊戲」,因爲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寶石)

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

Books.joins(:author).where { 
    (lower(title) =~ lower(search)) | 
    (lower(author.name) =~ lower(search)) 
} 
+0

你確定你使用的是區分大小寫的排序規則? MySQL結果集應該是什麼樣子? – Strawberry 2014-11-04 10:12:37

+0

是的,我已經使用'LOWER'轉換了案件,所以案件並不重要。 SQL結果只是返回「飢餓遊戲」。我將它添加到編輯 – hrsetyono 2014-11-04 10:13:44

回答

2

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

Replace le通過Sql Fiddle中的內部,您將獲得有和沒有作者的書籍。

在導軌中,您可以通過includes代替joins來實現左連接。因爲它保留了沒有關係的第一個表的數據,所以當您想要加載關係以防止N + 1查詢問題時,經常使用它。

+0

哇謝謝!以前從未正確學習過SQL。所以我不知道這個左右內聯加入。 – hrsetyono 2014-11-04 10:17:12

+2

我認爲這個特定的資源在SO內是相當皺眉的(http://meta.stackexchange.com/questions/87678/discouraging-w3schools-as-a-resource) – Strawberry 2014-11-04 10:19:40

+1

把它改成我能找到的唯一的其他英文鏈接。我想這個應該可以在SO ^^ http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/ – Syl 2014-11-04 10:25:37

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%'; 
+0

感謝您的回答!不幸的是,我必須選擇@Syl的答案,因爲他/她先回答。 – hrsetyono 2014-11-04 10:19:16