2009-08-16 10 views
1

に3つのテーブルを接続する私は、次の表を持って1つのクエリ

mid | date  | info 
1 | 2009-07-01 | no info yet 

音楽 - レビュー

mid | song    | buy 
1 | Example - Example | http://example.com 
2 | Exam - Exam  | http://example.com 

トラックリスト

tid | mid | mrid 
1 | 1 | 1 
2 | 1 | 2 

を持っていることも可能であるミックスあなたがリンクできるSQLクエリこれらはすべて1つになっていますか? ...

date  | info  | tracklist 
2009-07-01 | no info yet | Example - Example http://example.com, Exam - Exam http://example.com 

またはただし、この結果が返されるか、この必要性は私がミックスからMIDを取得してから行う2つのSQL querysをすることになります。

ので、私の結果は次のように判明するだろうそこからトラックリストを取得するクエリ? MySQLの

+0

私はあなたのサンプルコードに間違いがあると思います。音楽レビューテーブルは 'mid 'ではなく' mrid'によってインデックス付けされるべきですか?それとも、ミックス・テーブルを参照していますか? – Anthony

+0

また、私はデータのアーキテクチャが私にとって意味があるとは確信していません。曲情報が表示される唯一の場所は「音楽レビュー」です。これは、私が知るところでは、レビューデータはありません。おそらく、「音楽レビュー」は曲に関する情報を参照しているように見えるので、「曲情報」にする必要があります。アーティストと曲名の両方に1つの列しかない理由は何ですか?これはソートをより堅牢にする2つの列になる可能性があります。 – Anthony

+0

と最後に:なぜ、私が聞くかもしれませんが、最初に質問した結果が欲しいですか?あなたの問題は、より高いレベルで有効であり、私は自分自身を把握しなければなりませんでした。しかし、トラックリストに既にインデックスがある場合、なぜすべてのトラックリスト情報を結果にマージしようとしていますか?なぜ、3つのテーブルの結合(mherrenが正しかったように)だけでなく、トラックリストの列をあなたのトラックリストのインデックスにするのはなぜですか?特定の行のトラックリストの詳細を表示するには、そのトラックリスト番号だけのクエリを実行しますか? – Anthony

答えて

2

:mherrenから適応として

SELECT mixes.date, mixes.info, 
    GROUP_CONCAT(DISTINCT music-review.song + ' ' + music-review.buy 
     ORDER BY music-review.mid ASC SEPARATOR ', ') 
FROM mixes 
JOIN tracklist ON tracklist.mid = mixes.mid 
JOIN music-review ON music-review.mrid = tracklist.mrid 
GROUP BY mixes.date, mixes.info 
0

これは動作します:

SELECT mixes.`date`, mixes.info, 
CONCAT(GROUP_CONCAT(DISTINCT `music-review`.song , ' ' , `music-review`.`mid` 
ORDER BY `tracklist`.`tid` ASC SEPARATOR ', ')) as `tracklist` 
FROM mixes 
JOIN tracklist ON tracklist.`mid` = mixes.`mid` 
JOIN `music-review` ON tracklist.`mrid` = `music-review`.`mid` 
WHERE `mixes`.`date`='2009-07-01' 
GROUP BY mixes.`date`, mixes.info; 

それは私がなっていた宣伝文句問題を修正したが、一つのことは、GROUP_CONCATが1024に設定され、最大の制限を有していることですこれは変更することができますによって

SET GLOBAL group_concat_max_len=4096 
0

私は非常に多くのコメントを残し、私はそれがより有用と思ったoあなたのアーキテクチャーに対する修正を提案してください。しかし、私はmherrenがすでにあなたの実際の懸念にうまく対処していると思うので、投票は評価されますが、私はこれを正しい「回答」と見なすべきではないと思います。

データの配置方法を再検討する必要があると思います。具体的には、「音楽レビュー」のためのテーブルがありますが、それは同時に外見に似ていると同時に、「ミックス」と「トラックリスト」を参照すると少し冗長に見えます。 「ミックス」とは、作成されたとき、作成したときのようなミックスに関する情報のことです。「トラックリスト」は「ミックス」内の曲のリストですが"あなたはこの試みた場合:

#song-info 
song_id | artist  | title   | online-store 
1  | The Airheads | Asthma Attack! | example.com/?id=123 
2  | The Boners | Bite the Boner | example.com/?id=456 
3  | Cats in Heat | Catching a Cold | example.com/?id=789 
4  | Dirty Djangos | Dig these Digits | example.com/?id=147 

#mixes 
mix_id | date  | info 
1  | 2009-07-01 | no info yet 
2  | 2009-07-02 | no info yet 

#mix_tracklist 
mix_id | song_id 
1  | 1 
1  | 2 
2  | 2 
2  | 3 

を今、あなたは可能なミックスのリストを持つことができ、ユーザーはミックス、実際の曲のために別のクエリを選択した場合。

ソングデータをすべて1つの列に入れるのは、その結果に情報がすぐに必要な場合、またはそのサブクエリの結果を条件とする条件がクエリ自体に含まれている場合にのみ行う必要があります。それぞれのトラックリストでミックスのリストを出力したい場合は、ミックスインデックスに基づいて各ミックスのクエリを実行する方がよいでしょう。 HTMLを出力するPHPの場合は、次のコードを使用します:

$mixes = mysql_query("SELECT * FROM mixes WHERE date > '$last_week'"); 

while($mix = mysql_fetch_assoc($mixes)) { 
    $mix_id = $mix['mix_id']; 
    $mix_date = date('m/d/Y', strtotime($mix['mix_id'])); 
    $mix_info = $mix['mix_id']; 
    echo <<<EOT 
    <h2 class="mix_number">$mix_number</h2> 
    <p class="mix_date">$mix_date</p> 
    <p class="mix_info">$mix_info</p> 
    <h3>Track Listing:</h3> 
      <ul class="tracklist"> 
    EOT; 
    $tracks = mysql_query("SELECT song.artist artist, 
            song.title title, 
            song.online-store url 
            song.song_id 
          FROM song-info song 
          JOIN mix_tracklist tracks ON (tracks.song_id = song.song_id) 
          WHERE tracks.mix_id = '$mix_id' 
          ORDER_BY song_id); 
    while ($track = mysql_fetch_assoc($tracks)) { 
      $artist = $track['artist']; 
      $song_name = $track['title']; 
      $song_url = $track['url']; 
      echo <<<EOT 
       <li><a href="$song_url">$artist &ndash; $song_name</a></li> 
    EOT; 
    } 
    echo "</ul>"; 
    }