You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL新手求助:如何用单条语句关联三张表查询歌曲及歌手信息

查询歌曲标题及对应歌手列表的SQL方案

嘿,作为SQL初学者,多表关联确实是个需要慢慢上手的知识点,不过你的场景特别典型,咱们一步步来搞定它!

首先先理清楚三张表的关联逻辑:

  • songs 表和 song_artists 表通过**song_id**关联(也就是 songs.id = song_artists.song_id)
  • song_artists 表和 artists 表通过**artist_id**关联(也就是 song_artists.artist_id = artists.id)

下面分两种场景给你对应的解决方案:

1. 基础关联查询(单条记录对应单个歌手)

如果只是想看到每首歌和对应的单个歌手(一首歌有多个歌手时会显示多行),用基础的JOIN语句就可以:

SELECT s.title, a.name AS artist_name
FROM songs s
JOIN song_artists sa ON s.id = sa.song_id
JOIN artists a ON sa.artist_id = a.id
ORDER BY s.title;

针对你给出的《Memories》例子,这条语句会返回:

titleartist_name
MemoriesDavid Guetta
MemoriesKid Cudi

2. 合并歌手列表(一行显示所有关联歌手)

如果想要把同一首歌的所有歌手合并成一个逗号分隔的列表(比如David Guetta, Kid Cudi),不同数据库有对应的聚合函数,下面是主流数据库的实现:

MySQL / MariaDB

使用 GROUP_CONCAT 函数:

SELECT s.title, GROUP_CONCAT(a.name SEPARATOR ', ') AS artist_list
FROM songs s
JOIN song_artists sa ON s.id = sa.song_id
JOIN artists a ON sa.artist_id = a.id
GROUP BY s.id, s.title
ORDER BY s.title;

你的例子数据会返回:

titleartist_list
MemoriesDavid Guetta, Kid Cudi

PostgreSQL

使用 STRING_AGG 函数:

SELECT s.title, STRING_AGG(a.name, ', ' ORDER BY a.name) AS artist_list
FROM songs s
JOIN song_artists sa ON s.id = sa.song_id
JOIN artists a ON sa.artist_id = a.id
GROUP BY s.id, s.title
ORDER BY s.title;

SQL Server

SQL Server 2017及以上版本可以用 STRING_AGG:

SELECT s.title, STRING_AGG(a.name, ', ') AS artist_list
FROM songs s
JOIN song_artists sa ON s.id = sa.song_id
JOIN artists a ON sa.artist_id = a.id
GROUP BY s.id, s.title
ORDER BY s.title;

如果是更早的版本,用 STUFF + FOR XML PATH 的组合实现:

SELECT DISTINCT
    s.title,
    STUFF((
        SELECT ', ' + a.name
        FROM song_artists sa
        JOIN artists a ON sa.artist_id = a.id
        WHERE sa.song_id = s.id
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS artist_list
FROM songs s
ORDER BY s.title;

Oracle

使用 LISTAGG 函数:

SELECT s.title, LISTAGG(a.name, ', ') WITHIN GROUP (ORDER BY a.name) AS artist_list
FROM songs s
JOIN song_artists sa ON s.id = sa.song_id
JOIN artists a ON sa.artist_id = a.id
GROUP BY s.id, s.title
ORDER BY s.title;

小提醒

  • 上面用的是JOIN(内连接),只会返回有对应歌手信息的歌曲;如果想包含没有录入歌手的歌曲(比如纯音乐),可以把JOIN换成LEFT JOIN。
  • 分组时建议同时用songs.id和songs.title,避免出现不同ID但标题相同的歌曲被错误合并的情况。

内容的提问来源于stack exchange,提问作者Phil90

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:13:27