如何用SQL从多表查询并按指定格式输出学生成绩数据?
可以用SQL实现,具体方法如下
核心思路是关联三张表后按学生分组,将每个学生的科目成绩信息聚合拼接成指定格式的单行字符串,不同数据库的字符串聚合函数略有差异,以下是主流数据库的实现方案:
1. MySQL/MariaDB 实现
使用GROUP_CONCAT函数完成字符串聚合:
SELECT s.sname, GROUP_CONCAT( CONCAT(sub.subname, ' ', g.marks, ' ', g.grades) SEPARATOR ' ' ) AS result FROM student s JOIN grades g ON s.sid = g.sid JOIN subject sub ON g.subid = sub.subid GROUP BY s.sid, s.sname;
如果需要像示例那样对齐学生姓名(比如Bob ),可以用LPAD函数补空格:
SELECT LPAD(s.sname, 5, ' ') AS sname, -- 按最长姓名长度补空格对齐 GROUP_CONCAT( CONCAT(sub.subname, ' ', g.marks, ' ', g.grades) SEPARATOR ' ' ) AS result FROM student s JOIN grades g ON s.sid = g.sid JOIN subject sub ON g.subid = sub.subid GROUP BY s.sid, s.sname;
2. PostgreSQL 实现
使用STRING_AGG函数实现聚合:
SELECT s.sname, STRING_AGG( CONCAT(sub.subname, ' ', g.marks, ' ', g.grades), ' ' ) AS result FROM student s JOIN grades g ON s.sid = g.sid JOIN subject sub ON g.subid = sub.subid GROUP BY s.sid, s.sname;
姓名对齐同样可用LPAD函数,写法和MySQL一致。
3. SQL Server 实现
SQL Server 2017及以上版本支持STRING_AGG:
SELECT s.sname, STRING_AGG( CONCAT(sub.subname, ' ', g.marks, ' ', g.grades), ' ' ) AS result FROM student s JOIN grades g ON s.sid = g.sid JOIN subject sub ON g.subid = sub.subid GROUP BY s.sid, s.sname;
低版本SQL Server需用STUFF结合FOR XML PATH实现聚合:
SELECT s.sname, STUFF( ( SELECT ' ' + CONCAT(sub.subname, ' ', g.marks, ' ', g.grades) FROM grades g JOIN subject sub ON g.subid = sub.subid WHERE g.sid = s.sid FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 1, '' ) AS result FROM student s GROUP BY s.sid, s.sname;
补充说明
- 确保
grades表中每个学生的所有科目都有对应记录,否则会缺失科目信息; - 如果需要按固定科目顺序(如Maths→Science→Art)拼接,可在聚合函数中添加排序规则,比如MySQL的
GROUP_CONCAT(...) ORDER BY sub.subname,PostgreSQL的STRING_AGG(...) ORDER BY sub.subname。
内容的提问来源于stack exchange,提问作者Sara
相关产品推荐
相关产品推荐

