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

MySQL透视表实现:将grades表课程转为列展示成绩求助

嘿,我来帮你搞定这个MySQL行列转换的问题!你要做的其实是把行数据转成列(也就是透视表),先明确下你的表结构大概是这样的(方便后续示例):

CREATE TABLE grades (
    `Index number` INT, -- 注意字段名有空格,必须用反引号包裹
    coursecode VARCHAR(50),
    grades VARCHAR(10) -- 如果是分数也可能是INT/DECIMAL类型
);

下面分两种常见场景给你解决方案:

情况1:已知所有课程代码(静态透视)

如果你的课程列表是固定的(比如只有CS101、Math202、Eng303这几门),直接用CASE WHEN配合聚合函数就能实现:

SELECT 
    `Index number`,
    -- 每门课程对应一个列,用MAX过滤NULL值
    MAX(CASE WHEN coursecode = 'CS101' THEN grades END) AS CS101,
    MAX(CASE WHEN coursecode = 'Math202' THEN grades END) AS Math202,
    MAX(CASE WHEN coursecode = 'Eng303' THEN grades END) AS Eng303
FROM grades
GROUP BY `Index number`;

小说明:

  • 这里用MAX是因为每个学生每门课只会有一条成绩,聚合函数会自动忽略NULL值,用SUM或MIN也能达到同样效果
  • 字段名Index number有空格,必须用反引号``包裹,否则MySQL会报错

情况2:课程代码动态变化(动态透视)

如果课程会新增或者数量很多,静态写法就太麻烦了,这时候可以用动态SQL自动生成透视语句:

-- 先清空变量
SET @sql = NULL;

-- 自动拼接所有课程对应的CASE语句
SELECT
    GROUP_CONCAT(DISTINCT
        CONCAT(
            'MAX(CASE WHEN coursecode = ''',
            coursecode,
            ''' THEN grades END) AS `',
            coursecode,
            '`'
        )
    ) INTO @sql
FROM grades;

-- 组装完整的SELECT语句
SET @sql = CONCAT('SELECT `Index number`, ', @sql, ' FROM grades GROUP BY `Index number`');

-- 执行动态SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

注意事项:

  • 如果课程数量特别多,可能需要调整group_concat_max_len参数(默认长度有限),可以先执行SET SESSION group_concat_max_len = 100000;来临时扩大长度
  • 动态SQL需要你有足够的数据库权限(一般WAMP默认权限是足够的)
  • 如果grades是数值类型,把MAX换成SUM或AVG都可以,结果一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:12:59