2012-03-06 5 views
3

ポップとエレクトロニックの両方のジャンルを持つデータベースのトラックの曲名をプルできるMySQLクエリを作成しようとしています。正規化されたデータベース - 1から全部 - 結合されたすべてのデータセットを検索

+----------------------------------------------------+ 
TABLE: SONG 
+----------------------------------------------------+ 
song_id  | title    | 
1  | song name | 


+----------------------------------------------------+ 
TABLE: GENRE 
+----------------------------------------------------+ 
genre_id   | name   | 
1   | Pop  |     
2   | Electronic |   


+----------------------------------------------------+ 
TABLE: SONG_GENRE 
+----------------------------------------------------+ 
genre_id  | song_id | 
1   | 1  | 
2   | 1  | 

このSQLは、明らかに1のgenre_idと2の両方を返すために行くことはありませんが、私は立ち往生午前ところ、これがある限り、動作しません。

SELECT DISTINCT song.song_id, song.title 
        FROM song 
        LEFT JOIN song_genre ON song_genre.song_id = song.song_id 
        LEFT JOIN genre ON genre.genre_id = song_genre.genre_id 
        WHERE genre.genre_id ='1' 
        AND genre.genre_id='2' 

誰かが正しい方向に私を指すことができたなら、私は最も素晴らしいでしょう!

答えて

3

ここでそれを行うための一つの方法です:かもしれない

SELECT DISTINCT song.song_id, song.title 
    FROM song 
    INNER JOIN (SELECT songid FROM song_genre WHERE song_genre.genre_id ='1') genre1 
     ON genre1.song_id = song.song_id 
    INNER JOIN (SELECT songid FROM song_genre WHERE song_genre.genre_id ='2') genre2 
     ON genre2.song_id = song.song_id 

もう一つの方法は、 もっと効率的。これは、song_genreにdupsがないことを前提としています。 COUNT(*)= Xここで、Xはリストされたジャンルの数に等しい。

SELECT DISTINCT song.song_id, song.title 
FROM song 
INNER JOIN (SELECT songid, COUNT(*) FROM song_genre 
WHERE genre_id IN ('1','2') 
GROUP BY songid HAVING COUNT(*) = 2) genre1 ON genre1.song_id = song.song_id 
+0

ご協力ありがとうございます。これはうまくいきますが、私はこれがいかにうまくスケールされるかわかりません。たとえば、楽器、気分などを追加した場合、かなり大きなクエリが作成されます。これはどれくらい効果的でしょうか?私のデータベース設計に何か問題がありますか?あれば、どのように改善することができますか? – Sharpedges

+0

もっと管理しやすいSQLの答えが更新されました。あなたのデザインは大丈夫です - 私はいつも正しく正規化されていると思っています。これまでのパフォーマンスはあまり心配しません。後で問題が発生した場合は、非正規化を検討することができます。 –

+0

これは素晴らしい答えです。私は私が必要としていることを正確に行うことができました。ご協力ありがとうございました。 – Sharpedges

0
   WHERE genre.genre_id ='1' 
       AND genre.genre_id='2' 

が適切ですか?

if、これはどちらの場合も真でなければならないが、行ごとにgenre_idが1つしかないことを意味する! 'OR' またはと おそらくチェーンこれを... genre.genre_id IN(1,2)

2

データと仮定すると、あなたのサンプルのように正規化された文字である:

SELECT 
    song.song_id, 
    song.title 
FROM 
    song 
     INNER JOIN song_genre ON song_genre.song_id = song.song_id 
     INNER JOIN genre ON genre.genre_id= song_genre.genre_id 
WHERE 
    genre.genre_id in ('1', '2') 

あなたのコメントに応じて変更されました:

SELECT 
    song.song_id, 
    song.title 
FROM 
    song 
     INNER JOIN song_genre ON song_genre.song_id = song.song_id 
     INNER JOIN genre g1 ON g1.genre_id = song_genre.genre_id 
     INNER JOIN genre g2 ON g2.genre_id = song_genre.genre_id 
WHERE 
    g1.genre_id = '1' and 
    g2.genre_id = '2' 
+0

これは、Pop OR Electronicというジャンルのすべての結果を返します。ポップとエレクトロニックの両方のジャンルを持つ検索結果のみを検索したいのですが? – Sharpedges

関連する問題