导读:本期聚焦于小伙伴创作的《SQL查询中如何将行数据转换为列显示?利用CASE WHEN实现简单PIVOT》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL查询中如何将行数据转换为列显示?利用CASE WHEN实现简单PIVOT》有用,将其分享出去将是对创作者最好的鼓励。

在SQL数据处理过程中,行转列是常见需求,比如将不同类别的统计数据从多行合并为单行多列展示,使用CASE WHEN语句就能实现类似PIVOT的效果,无需依赖数据库特定的PIVOT关键字,兼容性更好。

行转列的核心逻辑

行转列的本质是根据某一列的枚举值,将其他列的数值拆分到多个新的列中。CASE WHEN语句的作用就是判断目标列的枚举值,当匹配到对应值时返回需要展示的字段值,不匹配时返回空值或者默认值,最后配合聚合函数将同一行的多个结果合并。

示例表结构与测试数据

首先创建一张学生成绩表,存储每个学生在不同科目下的分数,表结构如下:

-- 创建学生成绩表
CREATE TABLE student_score (
    student_id INT,
    student_name VARCHAR(50),
    subject VARCHAR(20),
    score INT
);

-- 插入测试数据
INSERT INTO student_score (student_id, student_name, subject, score) VALUES
(1, '张三', '语文', 85),
(1, '张三', '数学', 92),
(1, '张三', '英语', 78),
(2, '李四', '语文', 90),
(2, '李四', '数学', 88),
(2, '李四', '英语', 95),
(3, '王五', '语文', 76),
(3, '王五', '数学', 89),
(3, '王五', '英语', 82);

使用CASE WHEN实现行转列

我们需要将每个学生的语文、数学、英语成绩分别转为列展示,每个学生对应一行数据,包含三个科目对应的分数列。查询语句如下:

SELECT
    student_id,
    student_name,
    -- 语文成绩列,匹配科目为语文时返回分数,否则返回NULL
    MAX(CASE WHEN subject = '语文' THEN score ELSE NULL END) AS 语文,
    -- 数学成绩列,匹配科目为数学时返回分数,否则返回NULL
    MAX(CASE WHEN subject = '数学' THEN score ELSE NULL END) AS 数学,
    -- 英语成绩列,匹配科目为英语时返回分数,否则返回NULL
    MAX(CASE WHEN subject = '英语' THEN score ELSE NULL END) AS 英语
FROM student_score
-- 按学生和姓名分组,将同一学生的多行数据合并为一行
GROUP BY student_id, student_name
ORDER BY student_id;

执行上述查询后,得到的结果如下:

student_idstudent_name语文数学英语
1张三859278
2李四908895
3王五768982

关键细节说明

  • 聚合函数的选择:这里使用MAX函数是因为每个学生在每个科目下只有一条分数记录,MAX会取到唯一的分数值,也可以使用SUMMIN等聚合函数,只要保证同一分组下对应条件的记录唯一即可。
  • ELSE子句的处理:如果不写ELSE NULL,CASE WHEN不匹配时会返回空,效果和ELSE NULL一致,但显式写出可读性更好。
  • 分组规则:GROUP BY必须包含所有非聚合的查询字段,也就是student_id和student_name,否则查询会报错。

动态科目场景的适配

如果科目是动态新增的,无法提前写死CASE WHEN的分支,可以通过拼接SQL的方式实现。首先查询所有不重复的科目,然后动态生成CASE WHEN的语句,最后执行拼接后的完整SQL。以下是MySQL动态行转列的示例逻辑:

-- 定义变量存储动态SQL
SET @sql = NULL;
-- 拼接CASE WHEN的字段部分
SELECT GROUP_CONCAT(DISTINCT
  CONCAT(
    'MAX(CASE WHEN subject = ''',
    subject,
    ''' THEN score ELSE NULL END) AS `',
    subject,
    '`'
  )
) INTO @sql
FROM student_score;

-- 拼接完整查询语句
SET @sql = CONCAT('SELECT student_id, student_name, ', @sql, 
                  ' FROM student_score GROUP BY student_id, student_name ORDER BY student_id');

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

适用场景总结

使用CASE WHEN实现简单PIVOT行转列的方式,适合科目、分类等枚举值固定的场景,兼容MySQL、PostgreSQL、SQL Server、Oracle等几乎所有关系型数据库。如果数据库支持原生PIVOT关键字,也可以结合使用,但CASE WHEN的方式在跨数据库迁移时不需要修改代码,维护性更强。

SQLCASE_WHENPIVOT行转列修改时间:2026-06-20 12:15:26

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。