MySQL LEFT JOIN多表逻辑问题

时间:2011-08-13 16:10:34

标签: php mysql

我有3张桌子:singerssongsalbums。它们都与singer_id

相关联

即使没有匹配的singer_id,我也需要获取所有这些内容。我设法通过这个查询得到了所有这些:

   SELECT singers.singer_name, albums.album_name, songs.song_name 
     FROM singers
LEFT JOIN albums ON singers.singer_id = albums.singer_id 
LEFT JOIN songs ON albums.singer_id = songs.singer_id
    WHERE singer_id = ?

但问题是我可以;正确显示结果。

让我们说这位歌手有3张专辑和11首歌曲。这就是我展示它们的方式......

显示歌手姓名:

echo $results[0]['singer_name']

显示歌曲名称:

foreach($results as $song) {
   // PROBLEM: instead of getting 11 songs i'm getting 33 results so each song show up 3 times.
   echo $song['song_name'] 
}

显示相册:

foreach($results as $album) {
 // PROBLEM: i'm getting 33 albums instead of 3 each album shows up 3 times.
  echo $album['album_name'] 
}

编辑: 歌曲表中有对专辑表album_id的引用,但是还有没有专辑的歌曲,所以我需要通过singer_id

获得结果

我需要得到的是: 11首歌。 3张专辑。 1位歌手。

提前感谢。

编辑: 这个解决方案对我有用。 我想要的是获得指定歌手id和专辑的所有歌曲 我想要的结果看起来像这样。

singer_name : song_name     : album_name
...............................................................
Jay Z       : 99 Problems   : NULL
Jay Z       : Gotta Have It : Watch the Throne

所以我想要获得所有歌手的歌曲,即使他们还没有任何专辑。

这是我使用的查询。

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 = ?

感谢@knittl我得到了我需要的结果。

但现在还有另一个问题。 我有3张专辑和11首歌曲

歌曲显示正确,但当我在专辑上制作foreach循环时,我再次获得33张专辑....

如何正确显示相册?我只有3张专辑。

2 个答案:

答案 0 :(得分:2)

你想要所有歌曲。从歌曲中选择并执行左连接以从其他表中获取潜在数据(按顺序获得更好的表示):

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

答案 1 :(得分:0)

你想要的主要是歌曲,一首歌必须有艺术家,但可能有/或没有专辑:

SO:

SELECT     singers.singer_name, IF('' == albums.album_name, 'single', albums.album_name) AS album_name, songs.song_name 
FROM       songs   AS songs
RIGHT JOIN singers AS singers ON (singers.singer_id = songs.singer_id)
LEFT JOIN  albums  AS albums  ON (albums.singer_id = songs.singer_id)
WHERE      songs.singer_id = ?