2012-06-15 10 views
8

私はMySQLデータベースに2つのテーブルを持ち、1つはデータベース内のすべてのブックのライブラリで、もう1つは本に対応する個々のローを含んでいますユーザーのライブラリに保存します。例えばMySQL Left Outer Join、ユーザに属する2番目のテーブルの項目を除外

ライブラリ表

`id`  `title`... 
=====  =========== 
    1   Moby Dick 
    2   Harry Potter 

コレクション表

私がしているすべての書籍が表示されますクエリを実行されて何をしたいのか
`id`  `user`  `book` 
=====  ======  ======= 
    1   1   2 
    2   2   2 
    3   1   1 

はユーザーのコレクションにはありません。これは、私の知る限りだけで正常に動作し

SELECT * 
FROM `library` 
LEFT OUTER JOIN `collection` ON `library`.`id` = `collection`.`book` 
WHERE `collection`.`book` IS NULL 

:私はすべての書籍ではないで任意のユーザのコレクションを表示するには、このクエリを実行することができます。これをPHPMyAdminで実行すると、コレクションテーブルにないすべての書籍が作成されます。

ただし、特定のユーザーに制限するにはどうすればよいですか。たとえば、上記のダミーデータでは、ユーザー2がクエリを実行するとブック1になり、ユーザー1がクエリを実行する場合はブックはありません。

AND user=[id]を追加するだけでは機能しません。JOINという非常に限られた知識があり、私は本当にどこにもいません。

また、返される結果のID(表示されたクエリのうち、機能しないもの)は0です - 返されるIDがlibrary.idのものであることを確認するにはどうすればよいですか?結合テーブル内NULLは、ユーザーが彼/に持っていないために行(図書)となりますが何であれ、あなたは、特定のユーザーが持っている書籍のみをごLEFT JOIN選択を絞り込む必要があるでしょう

+0

実際のテーブル構造を表示し、発生したエラー(もしあれば)をお知らせください。あなたの質問には、あなたのテーブルの説明にない「記事」というフィールドがあります。 – bpeterson76

+0

おっと - 私はコピーして貼り付けたときに記事として残しました。それは "本"でなければなりません。私は質問を変更しました。 –

答えて

12

その後、彼女のコレクション:

SELECT 
    a.id, 
    a.title 
FROM 
    library a 
LEFT JOIN 
    (
     SELECT book 
     FROM collection 
     WHERE user = <userid> 
    ) b ON a.id = b.book 
WHERE 
    b.book IS NULL 

選択肢がある:

SELECT 
    a.id, 
    a.title 
FROM 
    library a 
WHERE 
    a.id NOT IN 
    (
     SELECT book 
     FROM collection 
     WHERE user = <userid> 
    ) 

はしかし、最初のソリューションは、MySQLは、各ROに一度NOT INサブクエリが実行されますように、より最適ですwはクエリ全体に対して1回だけではなく、直感的に言えば、MySQLがサブクエリを一度実行してリストとして使用すると思いますが、MySQLは相関サブクエリと非相関サブクエリを区別するほどスマートではありません。

hereを述べたように:

「問題は、INサブクエリを使用するステートメントのために、 オプティマイザは相関サブクエリとしてそれを書き換え、ということです。」

+0

ありがとう!それは完璧に働いた。どんな理由であれ、このJOINのものは私の頭を包み込むのが難しいです... –

+2

最後の段落は、 'IN'サブクエリが記述されていて、' NOT IN'サブクエリが記述されていないリンクを指しています。だから、あなたが暗示しているように、 'NOT IN'を使ったクエリはうまく最適化されていません。この素晴らしいブログ記事を見てください:[NOT INIS対NOT EXISTS vs. LEFT JOIN/IS NULL:MySQL](http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs- –

+0

私はそれが 'NOT IN'か' IN'かどうかは関係ありません。 'NOT'は単に' IN'から返されたブール値を反転します。興味深い記事だが、+1 –

3

これはいかがですか?それはちょうど私の頭の上から外れています - 私はすぐにテストするデータベースにアクセスすることはできません。(申し訳ございません)

SELECT 
    * 
FROM 
    library lib 
WHERE 
    lib.id NOT IN (
     SELECT 
     book 
     FROM 
     collection coll 
     WHERE 
     coll.user =[id] 
    ) 
; 
+0

ああ...アンドリューMが私にそれを打つのを見る:O) –

+0

助けてくれてありがとうと思う:P +1 –

+1

+1ありがとう。私はそれらを大いに必要とし、完全に新しいここにいる:O) –

関連する問題