SQL行转列实现问询:如何将现有表数据转换为指定输出格式
SQL行转列实现方案
根据你提供的原始表和目标输出结构,原始表为长表结构(每一行对应一个学生单门科目的分数),需要转换为宽表结构(每一行对应一个学生所有科目的分数),属于典型的行转列需求,以下为具体实现方案:
通用实现(兼容所有主流关系型数据库)
使用CASE WHEN搭配聚合函数的写法,可兼容MySQL、PostgreSQL、Oracle、SQL Server等所有主流数据库:
SELECT 学生姓名, MAX(CASE WHEN 科目 = '语文' THEN 分数 END) AS 语文, MAX(CASE WHEN 科目 = '数学' THEN 分数 END) AS 数学, MAX(CASE WHEN 科目 = '英语' THEN 分数 END) AS 英语 FROM 你的表名 GROUP BY 学生姓名;
- 字段名、科目取值请根据你实际的表结构调整,有多少个不同的科目就新增多少个
CASE WHEN分支 - 若同一学生同科目存在多条成绩记录,可根据需求将
MAX替换为SUM、AVG等对应聚合函数
不同数据库专属简化语法
MySQL
可使用IF函数简化判断逻辑:
SELECT 学生姓名, MAX(IF(科目 = '语文', 分数, NULL)) AS 语文, MAX(IF(科目 = '数学', 分数, NULL)) AS 数学, MAX(IF(科目 = '英语', 分数, NULL)) AS 英语 FROM 你的表名 GROUP BY 学生姓名;
SQL Server
支持PIVOT关键字直接实现行转列:
SELECT * FROM 你的表名 PIVOT ( MAX(分数) FOR 科目 IN ([语文],[数学],[英语]) ) AS pivot_result;
Oracle
同样支持PIVOT语法:
SELECT * FROM 你的表名 PIVOT ( MAX(分数) FOR 科目 IN ('语文' AS 语文, '数学' AS 数学, '英语' AS 英语) );
PostgreSQL
可通过tablefunc扩展的crosstab函数实现动态行转列:
-- 首次使用需先启用扩展 CREATE EXTENSION IF NOT EXISTS tablefunc; -- 行转列查询语句 SELECT * FROM crosstab( 'SELECT 学生姓名, 科目, 分数 FROM 你的表名 ORDER BY 1', 'SELECT DISTINCT 科目 FROM 你的表名 ORDER BY 1' ) AS result(学生姓名 VARCHAR, 语文 INT, 数学 INT, 英语 INT);
内容的提问来源于stack exchange,提问作者MRR
相关产品推荐
相关产品推荐

