SQL Server 纵表转横表与横表转纵表的实现方法
在处理关系型数据库数据时,经常遇到行列转换的需求,例如将多条成绩记录合并为一行展示,或将宽表拆分为规范的数据行。本文将介绍在 SQL Server 中利用 T-SQL 实现纵表与横表互转的两种核心方法:使用聚合函数配合条件判断,以及利用 UNION ALL 进行列展开。
1. 纵表转横表:行转列
在实际业务中,原始数据往往以“键-值”对的形式存储在纵表中(即每一行为一个属性记录)。为了生成类似 Excel 的透视报表,通常需要将不同的类别列转换为单独的字段。这一过程通常被称为“透视”(Pivot)。
转换目标:将包含课程和分数的多行记录,合并为以学生姓名为一行,各科目分数为列的宽表结构。
原始纵表结构 Table_A 示意图:

转换后的横表结构示意:

实现该逻辑的核心思路是分组后,针对每个特定的列值应用条件计算。以下是基于 CASE 表达式的标准写法:
SELECT Name, SUM(CASE WHEN Course = N'语文' THEN Grade ELSE 0 END) AS Chinese, SUM(CASE WHEN Course = N'数学' THEN Grade ELSE 0 END) AS Mathematics, SUM(CASE WHEN Course = N'英语' THEN Grade ELSE 0 END) AS English FROM dbo.Table_A GROUP BY Name;
关键点解析:
CASE ... WHEN ... THEN:用于在行级别筛选特定条件的数据,满足条件的返回对应分数,否则返回 0。SUM():由于每组内只有对应科目的那一行有值,其他行均为 0,因此求和即可得到该学生在该科目的最终得分。GROUP BY Name:确保按学生姓名聚合数据,每个学生仅输出一行结果。
2. 横表转纵表:列转行
反之,有时我们需要将宽表格式化为符合第三范式的长表格式,或者统一不同维度的查询接口。这种操作通常称为“逆透视”(Unpivot)。
待处理的横表结构 Table_B 示意图:

转换后的纵表结构示意:

实现方式是将每一列数据视为独立的集合,通过连接运算符将它们垂直堆叠在一起。以下是使用 UNION ALL 的标准脚本:
SELECT Name,'Chinese' AS Course,Chinese AS Score FROM dbo.Table_B UNION ALL SELECT Name,'Mathematics' AS Course,Mathematics AS Score FROM dbo.Table_B UNION ALL SELECT Name,'English' AS Course,English AS Score FROM dbo.Table_B ORDER BY Name,Course DESC;
逻辑说明:
SELECT ... FROM Table_B:分别提取每一门科目的数据作为独立的结果集。'CourseName' AS Course:因为原表中没有统一的“科目”字段,这里使用字面量常量手动构建这一列的值。AS Score:统一输出字段名,使最终结果的列结构与期望一致。UNION ALL:将所有查询结果垂直拼接。相较于UNION,ALL不会去重,执行效率更高,且此处不同列组合不会产生重复行,故推荐使用UNION ALL。
3. 适用场景与建议
上述方法是处理行列转换的基础手段。对于列数固定且已知的场景,直接使用 CASE WHEN 或 UNION ALL 语法清晰、易于维护。若面临列名动态变化的情况,则需结合动态 SQL 或专门的 PIVOT/UNPIVOT 关键字进行处理。
以上就是 SQL Server 纵表与横表相互转换的详细内容,更多关于 SQL 行列操作技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









