欢迎光临易鼎网
详情描述

一、使用 PIVOT 运算符

场景1:统计学生各科成绩

原始表 Scores: | StudentID | Subject | Score | |-----------|----------|-------| | 1 | Math | 90 | | 1 | English | 85 | | 2 | Math | 88 | | 2 | English | 92 |

目标:将科目转为列显示每个学生的成绩。

SELECT StudentID, [Math], [English]
FROM Scores
PIVOT (
    MAX(Score) 
    FOR Subject IN ([Math], [English])
) AS PivotTable;

结果: | StudentID | Math | English | |-----------|------|---------| | 1 | 90 | 85 | | 2 | 88 | 92 |

场景2:动态行转列(列数不固定)

若科目不固定,可以使用动态SQL:

DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX);

SELECT @cols = STUFF((
    SELECT DISTINCT ',' + QUOTENAME(Subject) 
    FROM Scores 
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '');

SET @query = '
SELECT StudentID, ' + @cols + '
FROM Scores
PIVOT (
    MAX(Score) 
    FOR Subject IN (' + @cols + ')
) AS PivotTable';

EXEC sp_executesql @query;

二、使用 CASE WHEN 实现

适用于简单场景或SQL Server旧版本:

SELECT 
    StudentID,
    MAX(CASE WHEN Subject = 'Math' THEN Score END) AS Math,
    MAX(CASE WHEN Subject = 'English' THEN Score END) AS English
FROM Scores
GROUP BY StudentID;

三、复杂场景示例

场景3:多指标转列(如同时转科目和学期)

原始表 StudentScores: | StudentID | Subject | Semester | Score | |-----------|----------|----------|-------| | 1 | Math | S1 | 90 | | 1 | Math | S2 | 85 | | 1 | English | S1 | 88 | | 1 | English | S2 | 92 |

目标:按学期和科目同时转列。

SELECT 
    StudentID,
    MAX(CASE WHEN Subject = 'Math' AND Semester = 'S1' THEN Score END) AS Math_S1,
    MAX(CASE WHEN Subject = 'Math' AND Semester = 'S2' THEN Score END) AS Math_S2,
    MAX(CASE WHEN Subject = 'English' AND Semester = 'S1' THEN Score END) AS English_S1,
    MAX(CASE WHEN Subject = 'English' AND Semester = 'S2' THEN Score END) AS English_S2
FROM StudentScores
GROUP BY StudentID;

四、使用 UNPIVOT(列转行)

逆操作示例:

-- 假设已有 pivot 结果表 PivotResult
SELECT StudentID, Subject, Score
FROM PivotResult
UNPIVOT (
    Score FOR Subject IN ([Math], [English])
) AS UnpivotTable;

五、实际应用注意事项

聚合函数选择PIVOT 必须使用聚合函数(如 MAX, SUM, AVG)。 列名处理:动态列名需注意特殊字符,建议使用 QUOTENAME()性能:大数据量时动态PIVOT可能影响性能,可考虑预先定义列。 兼容性CASE WHEN 兼容性更好,但代码较长;PIVOT 语法更简洁。

六、完整动态PIVOT模板

DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX);

-- 获取需要转换的列值
SELECT @cols = STRING_AGG(QUOTENAME(Subject), ',')
FROM (SELECT DISTINCT Subject FROM Scores) AS sub;

-- SQL Server 2017以下版本使用:
-- SELECT @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(Subject) ...), 1, 1, '')

SET @sql = N'
SELECT *
FROM Scores
PIVOT (
    MAX(Score)
    FOR Subject IN (' + @cols + ')
) AS p';

EXEC sp_executesql @sql;

根据具体需求调整聚合函数和条件即可应用于不同场景。

相关帖子
南京市代理做账|本地财务代账公司
南京市代理做账|本地财务代账公司
极端天气事件频发,对我们日常生活中常见的农作物品种选择有何深远启示?
极端天气事件频发,对我们日常生活中常见的农作物品种选择有何深远启示?
南京市建筑资质代办电话|专业公司注册
南京市建筑资质代办电话|专业公司注册
网络主播、自媒体博主等新兴职业,该如何合规地为自己缴纳职工社保?
网络主播、自媒体博主等新兴职业,该如何合规地为自己缴纳职工社保?
智能快递柜的普及,给我们的收件方式带来了哪些变化?
智能快递柜的普及,给我们的收件方式带来了哪些变化?
平顶山市危险化学品经营许可证办理流程|公司注册服务电话
平顶山市危险化学品经营许可证办理流程|公司注册服务电话
在进行专利许可谈判时,有哪些常见的条款需要特别注意和明确?
在进行专利许可谈判时,有哪些常见的条款需要特别注意和明确?
澄迈县餐饮许可证代办-中小企业注册,快速办理,欢迎电话咨询
澄迈县餐饮许可证代办-中小企业注册,快速办理,欢迎电话咨询
昆明市工商异常解除代办-注册公司代办服务
昆明市工商异常解除代办-注册公司代办服务
杭州市企业网站制作设计-精准获客软件,模板建站
杭州市企业网站制作设计-精准获客软件,模板建站
购买首套房后,关于房屋的日常维护与常见问题处理有哪些基础知识需要了解?
购买首套房后,关于房屋的日常维护与常见问题处理有哪些基础知识需要了解?
九江市卫生许可证代办|企业注册
九江市卫生许可证代办|企业注册
梅州市独立网站开发设计-网站搜索引擎优化,价格透明
梅州市独立网站开发设计-网站搜索引擎优化,价格透明
在办理集体户口迁出过程中,原单位不配合或已注销该如何处理解决?
在办理集体户口迁出过程中,原单位不配合或已注销该如何处理解决?
取消医保个人账户的跨省共济关系,是否会影响家人之前的结算记录?
取消医保个人账户的跨省共济关系,是否会影响家人之前的结算记录?
蚌埠市食品卫生许可证办理电话-营业执照注册代办
蚌埠市食品卫生许可证办理电话-营业执照注册代办
宁波市公司经营范围变更流程|个体户注册
宁波市公司经营范围变更流程|个体户注册
揭阳市品牌网站建设-短视频推广,专业团队
揭阳市品牌网站建设-短视频推广,专业团队
2026年,步态与声纹等生物识别信息的安全性面临哪些新的挑战?
2026年,步态与声纹等生物识别信息的安全性面临哪些新的挑战?
韶关市商城网站建设推广-房产网站建设,一站式服务
韶关市商城网站建设推广-房产网站建设,一站式服务