2012-03-13 55 views
1

我有兩個表之間的所有制關係, 說users(int user_id)user_books(int user_book_id,int user_id,int book_id) 和兩個附加表books(int book_id, varchar book_title, int author_id)authors (int author_id, varchar author_name)Mysql的加入尋找「失蹤」,「相關」行

給定一個具體的user_id我想要得到的書籍,用戶沒有,如果由作者寫的,他確實有他們寫的其他書籍。

因此,如果用戶有BOOK1(即在user_books中存在這一行),並且沒有BOOK2和BOOK3,這些BOOK2和BOOK3由與BOOK1相同的作者編寫,我希望獲得BOOK2和BOOK3的ID。

我想我可以使用SELECT WHERE NOT IN()來做到這一點,但出於性能方面的原因,我正在尋找一個基於聯接的解決方案。

+0

您是否嘗試過使用外連接? – 2012-03-13 11:55:14

+0

正如我所說的,我可以使用「select where not in」來寫這個,但我想使用連接。我知道它應該以某種方式使用左連接完成,但我不確定如何。 – epeleg 2012-03-13 12:34:38

+0

我也遇到了一個問題,即某些用戶可能已經擁有多個單一的user_book,因此連接會多次返回作者ID。 – epeleg 2012-03-13 12:39:48

回答

2

我檢查性能與一個「不」或其他解決方案,但我相信以下將工作:

select exist.userId, b.bookTitle, a.authorName 
from (select distinct ub.userId, b.authorId 
     from userBooks ub 
      inner join books b on b.bookId = ub.bookId 
     where ub.userId = @userId) exist 
    inner join Authors a on a.authorId = exist.authorId 
    inner join Books b on b.authorId = a.authorId 
    left outer join userBooks ub on ub.bookId = b.bookId and ub.userId = exist.userId 
where ub.userId is null 

派生表,發現所有用戶喜歡那麼的其餘部分的作者查詢查找同一作者的其他書籍

+2

你是對的 - 這是有效的,但它比使用IN和NOT IN要複雜得多(如你所期望的)。如果您對查詢做了解釋,則會看到有4個PRIMARY查詢和2個DERIVED查詢(其中一個使用臨時表)。而「select * from author_id in(從user_books中選擇author_id作爲ub將書籍作爲b在b.book_id = ub.book_id上)和book_id不在(從user_books中選擇book_id,其中user_id = @uid);」有四個查詢,全部使用where(因此符合索引加速的條件)。我同意測量這兩種方法是必要的,以挑選最好的。 – 2012-03-13 13:05:04

+0

@D Mac - 完全。你不能批發「不要使用不在」的方法。僅僅因爲可以在沒有它們的情況下做到這一點並不意味着你應該...更好地建議查看查詢的處理方式。我只是想證明可能,但我建議根據分析 – kaj 2012-03-13 13:18:15

+0

謝謝你們兩個,我會嘗試從這裏解決問題。 @D Mac在你提供的語法中,在第一個子查詢中有一個缺少user_id = @uid的地方,據我所知。甚至我的書籍表格都有一個關於author_id的索引,而book_id也沒有被使用。 – epeleg 2012-03-13 14:37:16