2012-03-13 22 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は私は2つのテーブル間の所有関係を持っている

具体的にはuser_idと書かれていますが、著者が書いた場所には、他の本が書かれているとは限りません。

ユーザーがBOOK1(すなわちuser_booksで、このための行が存在する)、どこでBOOK1と同じ作者によって書かれていることBOOK2とBOOK3を持っていないを持っているのであれば、私は、BOOK2およびBOOK3のIDを取得したいです。

私はSELECT WHERE NOT IN()を使用してこれを行うことができますが、パフォーマンス上の理由から私は結合ベースのソリューションを探しています。

+0

外部結合を試しましたか? –

+0

私が言ったように、私はこれを "select not in in"を使って書くことができますが、私は結合を使いたいと思います。私はそれが何らかの形で左結合を使用して行う必要があることを認識していますが、私は正確な方法を確信していません。 – epeleg

+0

私はまた、いくつかのユーザーがすでに1つのuser_book以上のものを持っているかもしれないという事実で問題を抱えています。 – epeleg

答えて

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問合せがあります(1つは一時表を使用しています)。一方、 "select * from author_id in user_books from ubはb.book_id = ub.book_idのbとして参加し、book_idはuser_id = @uidのuser_booksからbook_idを選択してください; 4つのクエリがあり、すべてがwhereを使用します(したがって、インデックス付きのアクセラレーションに適しています)。私は両方のアプローチを測定することがベストを選ぶために必要であることに同意します。 @D Mac - –

+0

。あなたは卸売りの "NOT INを使わないでください"というアプローチをとることはできません。それらがなくてもそれを行うことができるからといって、あなたがすべきことを意味するわけではありません...クエリが処理される方法を見ておくことを提案したように、ずっと優れています。私は可能性を実証したかっただけですが、分析に基づいてお勧めしたいと思います – kaj

+0

両方に感謝します。私はここから試してみることにします。 @D Macあなたが提供する構文では、私が知る限り、最初のサブクエリでuser_id = @uidが欠けています。さらに厳しい私の本の表にはauthor_idとbook_idにインデックスがあり、どちらも使われていません。 – epeleg

関連する問題