2011-08-13 18 views
0

WebページにMySQLクエリを正しく表示しようとしています。MySQLでヘルプが必要LEFT JOIN表示の問題

私は一緒に

singersを接続する4つの簡単な表があります。私はすでに管理singer_idalbum_idalbum_name

singer_idsinger_name

songssinger_idsong_namealbum_id

albumsを〜gこれらのテーブルはこのクエリを使用しています。

SELECT singers.singer_name, songs.song_name, albums.album_name 

FROM singers 
LEFT JOIN songs ON singers.singer_id = songs.singer_id 
LEFT JOIN albums ON albums.album_id = songs.album_id 
WHERE singers.singer_id = ? 
ORDER BY songs.song_id DESC 

私が今問題を抱えているのは、これらのテーブルを正しく表示することができないということです。

私は1枚のアルバムと11曲の歌手がいます。 これは私がこの歌手のために得ている結果です。

singer_name |  song_name  |  album_name 
__________________________________________________ 

singer name | song name  | album name 
singer name | song name  | album name 
singer name | song name  | album name 
singer name | song name  | album name 
singer name | song name  | album name 
singer name | song name  | album name 
singer name | song name  | album name 
singer name | song name  | album name 
singer name | song name  | album name 
singer name | song name  | album name 
singer name | song name  | album name 

1枚のアルバムを取得する代わりに、同じアルバムを11回取得しています。

ウェブページ私はforeach() を使ってアルバムを表示しています。アルバムは1つではなく、同じアルバムになっています。質問の今

....

がどのように私はアルバムにONLY 3回を表示することができますか?

(私は9枚のアルバムで歌手がいるかもしれないので、ハードコーディングなしで)。

ありがとうございました。

EDIT:

これは私が

     <?php foreach($results as $song): ?> 
         <tr> 
          <td></td> 
          <td> 
           <a href="/song/<?php echo urlencode($song['song_url']); ?>/" class="song"> 
            <span><?php echo $song['song_name']; ?></span> 
           </a> 
          </td> 
          <td> 
           <a href="/album/<?php echo urlencode($song['album_name']); ?>/" class="album"> 
            <?php echo $song['album_name']; ?> 
           </a> 
          </td> 
          <td> 
           <span class="time"> 
            <?php echo $song['song_time']; ?> 
           </span> 
          </td> 
          <td> 
           <a href="/search/?search=<?php echo urlencode($song['song_genre']); ?>" class="genre"> 
            <?php echo $song['song_genre']; ?> 
           </a> 
          </td> 
          <td><a href="#" class="play">נגן</a></td> 
         </tr> 
        <?php endforeach; ?> 

の曲を表示する方法です私は曲がどのアルバムに添付されていない場合でも、すべての曲を取得します。ちょうど私が欲しいもの。アルバムを表示して

問題:

    <?php foreach($results as $album): ?> 
        <li> 
         <a href="/album/<?php echo urlencode($album['url']); ?>/" class="album"> 
          <img src="/media/<?php echo $album['singer_dir'] . '/' . $album['album_thumb']; ?>" alt="" /> 
          <span class="album_name"><?php echo $album['album_name']; ?></span> 
         </a> 
        </li> 
       <?php endforeach; ?> 

この歌手は1枚のアルバムを持っていますが、私は11回のためにそれを取得します。このアルバムは11曲あります。 私は一度だけそれを表示する必要があります....

+0

どういう意味ですか?アルバムの名前のみを表示しますか? – EdoDodo

+0

[MySQL LEFT JOIN複数のテーブルの論理問題の可能な複製](http://stackoverflow.com/questions/7051658/) mysql-left-join-multiple-t ables-logic-problem) –

+0

@OMGPoniesこれは表示ではありません。 edododoは、アルバム名を表示するために結果をforeachループさせると、1つのアルバムと11の曲があると言うことができます.1回ではなく11回のアルバム名を取得します。 – ParparDromi

答えて

1

私の答えは質問how to display the changing values onlyに与えられ参照してください - 私はあなたのprevious questionにコメントしていることを述べました。基本的には、SQLクエリを分割することなく、PHPで結果をグループ化することです。

まず、次のクエリでquery your database

SELECT a.artist_name, COALESCE(b.album_name, '(no album)'), s.song_name, 
FROM songs s 
LEFT JOIN artists a 
ON s.singer_id = a.singer_id 
LEFT JOIN albums b 
ON s.album_id = b.album_id AND s.singer_id = b.singer_id 
ORDER BY a.artist_name, b.album_id, s.song_id # order by artist, album then song 

これはあなたの各行が(アーティスト名やアルバム名を含む)フル歌を表し結果セットを取得します - スプレッドシートを想像します - 、だからあなたが最初に参加を求めたのです。 (正しいORDER BYが、このために重要であり、一度だけの出力このテーブル、印刷アーティスト名やアルバムにしてみましょう

$prev = array('artist' => null, 'album' => null); 
while(($row = mysqli_fetch_assoc($result)) !== FALSE) { 
    // print groupings 
    if($row['artist_name'] != $prev['artist']) 
    displayArtist(); // only display the first occurrence of each artist 
    if($row['album_name'] != $prev['album']) 
    displayAlbum($row['album_name']); // same goes for albums 

    displaySong($row['song_name']); // but display every song 

    $prev['artist'] = $row['artist_name']; 
    $prev['album'] = $row['album_name']; 
} 

format*()のように簡単になります。

function displayArtist($artist_name) { 
    printf('<h1 class="artist">%s</h1>', htmlspecialchars($artist_name)); 
} 
function displayAlbum($album_name) { 
    printf('<h1 class="album">%s</h1>', htmlspecialchars($album_name)); 
} 
function displaySong($song_name) { 
    printf('<div class="song">%s</div>', htmlspecialchars($song_name)); 
} 

いますが、もちろん、テーブルのレイアウトを使用することができますあなたの質問のように

+0

ありがとうございました.... – ParparDromi

2

$結果変数について多くのことを知らないと(例えば、それはPDOオブジェクトまたは配列かもしれません、私は知らない)私の答えはaハック:

<?php foreach($results as $album): ?> 
    <li> 
     <a href="/album/<?php echo urlencode($album['url']); ?>/" class="album"> 
      <img src="/media/<?php echo $album['singer_dir'] . '/' . $album['album_thumb']; ?>" alt="" /> 
      <span class="album_name"><?php echo $album['album_name']; ?></span> 
     </a> 
    </li> 
    <?php break; ?> 
<?php endforeach; ?> 

個人的に私は自分のコードでこれをしないだろうが、あなたのコードの全体像と、何をしようとするの明確なアイデアをより多くなくて、それはそれが何であるかです。


編集1:

その場合は、あなたが必要とするすべては以下の通りです。 foreachのは不要である:

<li> 
    <a href="/album/<?php echo urlencode($result[0]['url']); ?>/" class="album"> 
     <img src="/media/<?php echo $result[0]['singer_dir'] . '/' . $result[0]['album_thumb']; ?>" alt="" /> 
     <span class="album_name"><?php echo $result[0]['album_name']; ?></span> 
    </a> 
</li> 

編集2:foreachのを使用して、この結果セットを超える

SELECT album_name 
FROM albums 
WHERE singer_id = ? 

とループ。

+0

素晴らしい。それはうまくいったけど、あなたが自分のコードに入れてしまいましたので、より良い答えを得なければならないので、私は$結果についてあなたに教えてくれるでしょう。 $結果はすべての曲と歌手情報アルバムはまさに私の質問の表に見られるものです。 – ParparDromi

+0

私はちょうど提供した情報に基づいて更新しました。 – Gerry

+0

すっごく寂しいです。 thatsハードコードは、この特定の歌手が5つのアルバムを持っていて1つではない場合、私は何をしましたか、私は質問を分割しなければならないと思います。 – ParparDromi

1

LEFT OUTER JOINメソッドはあなたが見たようにデザインされており、デカルト積の結果としてアルバムを繰り返す必要があります。

あなたの意見は分かりませんが、私はあなたの質問を2通り解釈しました。 1.歌手を繰り返し、曲を繰り返し、アルバムを繰り返す。 2.反復しない歌手/曲。アルバムをグループ化するだけです。

ウェイ1の場合、答えは簡単です。 distinctキーワードを追加する。 私はあなたが方法2を意味したと確信しています。反復情報を管理する必要があります。 htmlテーブルを使用して出力する場合は、rowspanという属性が役立ちます。

データ例:

CREATE TABLE t 
(a  varchar(25) 
, b  varchar(25) 
, c_id integer  
, c  varchar(25) 
); 

INSERT INTO t VALUES ('2ne1', 's1', 1, 'lonely'); 
INSERT INTO t VALUES ('2ne1', 's2', 1, 'lonely'); 
INSERT INTO t VALUES ('2ne1', 's3', 1, 'lonely'); 
INSERT INTO t VALUES ('2ne1', 's4', 1, 'lonely'); 
INSERT INTO t VALUES ('2ne1', 's5', 1, 'lonely'); 

INSERT INTO t VALUES ('anonymous', 'rock1', 2, 'um album'); 
INSERT INTO t VALUES ('anonymous', 'rock2', 2, 'um album'); 
INSERT INTO t VALUES ('anonymous', 'rock3', 2, 'um album'); 

コード例:

<?php 

$conn = mysql_connect('localhost', '..', ',,') 
    OR die (mysql_error()); 
mysql_select_db('test') 
    OR die (mysql_error()); 
$rs = mysql_query 
    ('select t.a, t.b, r.span, t.c_id, t.c '. 
     'from t        '. 
     'join         '. 
     '(select c_id, count(c) span   '. 
     ' from t        '. 
     ' group by c_id) r     '. 
     ' on t.c_id = r.c_id    ') 
    OR die (mysql_error()); 

echo "<html><table border=1>\n"; 
$old_c_id = -1; 
while ($row = mysql_fetch_array($rs, MYSQL_ASSOC)) { 
    echo "<tr>"; 
    echo "<td>".htmlspecialchars($row['a'])."</td>\n"; 
    echo "<td>".htmlspecialchars($row['b'])."</td>\n"; 
    if ($old_c_id != $row['c_id']) 
    { 
     $old_c_id = $row['c_id']; 
     echo sprintf("<td rowspan=%d>", $row['span']) 
      . htmlspecialchars($row['c']) 
      . "</td>\n"; 
    } 
    echo "</tr>\n"; 
} 
echo "</table></html>"; 

?> 
関連する問題