SQL Server多行多列变一行一列,从PIVOT到JSON的灵活处理方案

admin
本文介绍了SQL Server中多行多列转单行单列的高效处理方案,详细阐述了如何从传统的PIVOT操作过渡到JSON格式的灵活应用,通过代码示例展示了结合两者优势的解决方案,旨在解决数据透视难题,提升查询的灵活性与效率。

在数据库查询和数据报表开发中,我们经常遇到这样的需求:将一张“长格式”的数据表,转换成“宽格式”的表格,也就是实现SQL Server多行多列变一行一列的操作,这种操作通常被称为“数据透视”。

在学生成绩表中,每一行代表一个学生的单科成绩,我们需要将其转换为每一行代表一个学生,且包含所有科目成绩的格式。

本文将介绍两种最主流的方法:传统的 PIVOT 操作和现代的 FOR JSON 方法,并对比它们的优缺点。

SQL Server多行多列变一行一列,从PIVOT到JSON的灵活处理方案

场景模拟

我们构建一个简单的数据表 StudentScores,包含学生姓名、科目和分数:

CREATE TABLE StudentScores (
    StudentName NVARCHAR(50),
    Subject NVARCHAR(50),
    Score INT
);
INSERT INTO StudentScores VALUES 
    ('张三', '语文', 85),
    ('张三', '数学', 92),
    ('张三', '英语', 78),
    ('李四', '语文', 76),
    ('李四', '数学', 88),
    ('李四', '英语', 95);

目前的查询结果是一个标准的“多行多列”结构,我们的目标是将其变为“一行一列”的宽表结构。

方法一:使用 PIVOT(透视)运算符

PIVOT 是 SQL Server 中专门用于行转列的运算符,它通过聚合函数(如 MAX, SUM)将指定的列值旋转为新的列名。

语法核心: SELECT ... FROM ... PIVOT (聚合函数(列) FOR 转换列 IN (目标列列表))

代码示例:

SELECT * 
FROM (
    -- 子查询:先按学生分组
    SELECT StudentName, Subject, Score 
    FROM StudentScores
) AS SourceTable
PIVOT (
    -- 聚合函数:取最大分(也可以是 SUM)
    MAX(Score) 
    -- FOR 关键字:将 Subject 列的值变为新列名
    FOR Subject IN ([语文], [数学], [英语])
) AS PivotTable;

结果展示: 数据已经成功实现了SQL Server多行多列变一行一列,每一行代表一个学生,列名对应具体的科目。

局限性: PIVOT 的缺点是必须显式列出所有的目标列(如 [语文], [数学]),如果科目是动态变化的,编写静态的 PIVOT 语句会非常麻烦,这时就需要配合动态 SQL 使用。

方法二:使用 FOR JSON PATH(JSON 透视)

如果你的 SQL Server 版本是 2016 或更高版本,FOR JSON 是一个更现代、更强大的选择,它不需要预先知道列名,能够将多行数据自动合并为一个 JSON 对象,非常适合 Web API 开发或复杂的报表输出。

语法核心: SELECT ... FROM ... FOR JSON PATH

代码示例:

SELECT 
    StudentName,
    Subject,
    Score
FROM StudentScores
FOR JSON PATH, ROOT('StudentList');

结果展示: 这会返回一段 JSON 字符串:

[
  {
    "StudentName": "张三",
    "Score": {
      "语文": 85,
      "数学": 92,
      "英语": 78
    }
  },
  ...
]

虽然这返回的是文本,但在逻辑上它完美地实现了**SQL Server多行

文章版权声明:除非注明,否则均为xmsdn原创文章,转载或复制请以超链接形式并注明出处。

取消
微信二维码
微信二维码
支付宝二维码