0

I am making a music classification database using PHP and MySQL. I have three tables:

Song:

ID  | Title
------------------------
1   | Example Song

Genre:

ID  | Name
------------------------
1   | Classical
2   | Instrumental

SongGenre

SongID | GenreID
----------------
1      | 1
1      | 2

My Query is:

SELECT s.title, GROUP_CONCAT(DISTINCT g.name SEPARATOR ', ')
FROM song s    
LEFT JOIN songgenre sg ON s.id=sg.s_id
LEFT JOIN genre g ON sg.genreid = g.id

I'm using GROUP_CONCAT to allow for multiple genres as shown:

Title: "Example Song" Genres: Classical, Instrumental

I wish to generate a link in PHP for each genre, so that if the user clicks on "Classical" they are brought to more songs listed as Classical. The issue is, I am unsure how to give each genre its' own link. The issue with GROUP_CONCAT is that both genres are returned together in the same row, and I am unsure how to split the row apart to add a link to each separate genre.

7
  • the link would trigger a new query, which would select based on genre - well i think thats what you are asking Commented Mar 25, 2015 at 0:04
  • @Dagon I am aware how to actually create the query, my question is rather how to treat each genre as it's own link. I wish to have each genre as its' own separate link, which I am unaware how to do. I will update the question to make that more clear. Commented Mar 25, 2015 at 0:06
  • <a href="search.php?genre=1">Classical</a> Commented Mar 25, 2015 at 0:10
  • @Dagon My issue is that MySQL returns "Classical, Instrumental" as one row, and I don't know how to actually split those apart to add the <a> attribute. Commented Mar 25, 2015 at 0:13
  • explode() on the comma, then loop Commented Mar 25, 2015 at 0:15

2 Answers 2

1

a very basic example as requested by OP

$var="Classical, Instrumental";

$each=explode(', ',$var);

foreach($each as $v){
echo '<a href="search.php?genre='.$v.'">'.$v.'</a>';
}
Sign up to request clarification or add additional context in comments.

2 Comments

I'll just state the obvious here and point out that this approach will fail if a genre name contains a comma. Indeed, this approach is the third sign of "Pinball Programming" listed in the excellent article Signs that you're a bad programmer.
I embrace my badness.
1

Don't group within the database layer—return an ungrouped (but sorted) recordset to PHP and handle it from there:

$qry = $pdo->query('
  SELECT   sg.SongID, sg.GenreID, s.Title, g.Name
  FROM     song s
             LEFT JOIN songgenre sg ON s.ID = sg.SongID
             LEFT JOIN genre g ON sg.GenreID = g.ID
  ORDER BY sg.SongID, sg.GenreID
');

if ($qry) {
  echo '<ul class="songs">';

  $row = $qry->fetch();
  while ($row) {
    $current_song = $row['SongID'];

    echo '<li>'
       ,   '<span class="title">', htmlentities($row['Title']), '</span>'
       ,   '<ul class="genres">';
    do {
      echo   '<li>'
         ,     '<a href="genre.php?id=', intval($row['GenreID']), '">'
         ,       htmlentities($row['Name'])
         ,     '</a>'
         ,   '</li>';
    } while ($row = $qry->fetch() and $row['SongID'] == $current_song);

    echo   '</ul>'
       , '</li>';
  }

  echo '</ul>';
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.