数据库:SQLServer 实现行转列、列转行用法笔记

数据库:SQLServer 实现行转列、列转行用法笔记



数据库:SQLServer 实现行转列、列转行用法笔记

在许多的互联网项目当中,报表开发是整个项目当中很重要的一个功能模块。其中会有一些比较复杂的报表统计需要行转列或者列转行的需求。今天给大家简单介绍一下在SQLServer当中如何使用PIVOT、UNPIVOT内置函数实现数据报表的行转列、列转行。有需要的朋友可以一起学习一下。


一、PIVOT、UNPIVOT用途

官方解释:可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式更改为另一个表。PIVOT 通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合。UNPIVOT 与 PIVOT 执行相反的操作,将表值表达式的列转换为列值。
注意:UNPIVOT运算符通过将列旋转到行来执行PIVOT的反向操作,UNPIVOT 并不完全是 PIVOT 的逆操作。PIVOT 执行聚合,并将多个可能的行合并为输出中的一行。UNPIVOT 不重现原始表值表达式的结果,因为行已被合并。另外,UNPIVOT 输入中的 NULL 值也在输出中消失了。如果值消失,表明在执行 PIVOT 操作前,输入中可能就已存在原始 NULL 值。

二、PIVOT语法格式

SELECT <非透视的列>,
    [第一个透视的列] AS <列名称>,
    [第二个透视的列] AS <列名称>,
    …
    [最后一个透视的列] AS <列名称>,
FROM
    (<生成数据的 SELECT 查询>)
    AS <源查询的别名>
PIVOT
(
    <聚合函数>(<要聚合的列>)
FOR
[<包含要成为列标题的值的列>]
    IN ( [第一个透视的列], [第二个透视的列],
    … [最后一个透视的列])
) AS <透视表的别名>
<可选的 ORDER BY 子句>;

三、行转列示例说明

-- 创建测试表 学习成绩统计表CREATE TABLE ScoreStatistics( UserName NVARCHAR(20), --学生姓名 SubjectName NVARCHAR(30), --科目名称 Score FLOAT, --成绩)-- 插入测试数据INSERT INTO ScoreStatistics SELECT '小王', '语文', 100INSERT INTO ScoreStatistics SELECT '小王', '数学', 90.5INSERT INTO ScoreStatistics SELECT '小王', '英语', 88INSERT INTO ScoreStatistics SELECT '小王', '历史', 65INSERT INTO ScoreStatistics SELECT '小李', '语文', 81INSERT INTO ScoreStatistics SELECT '小李', '数学', 99INSERT INTO ScoreStatistics SELECT '小李', '英语', 95INSERT INTO ScoreStatistics SELECT '小李', '历史', 90INSERT INTO ScoreStatistics SELECT '小刘', '语文', 90INSERT INTO ScoreStatistics SELECT '小刘', '数学', 85INSERT INTO ScoreStatistics SELECT '小刘', '英语', 59INSERT INTO ScoreStatistics SELECT '小刘', '历史', 98-- 传统写法select UserName, max(case SubjectName when '语文' then Score else 0 end)语文, max(case SubjectName when '数学'then Score else 0 end)数学, max(case SubjectName when '英语'then Score else 0 end)英语, max(case SubjectName when '历史'then Score else 0 end)历史from ScoreStatisticsgroup by UserName-- PIVOT 写法更简洁SELECT * FROM ScoreStatisticsAS PPIVOT( SUM(Score/*行转列后 列的值*/) FOR p.SubjectName/*需要行转列的列*/ IN ([语文],[数学],[英语],历史 /*列的值*/)) AS T-- order by 语文 desc 具体科目排序-- order by username desc -- 姓名排序-- 动态拼接列的示例DECLARE @sql_str VARCHAR(8000); -- 要执行的sql--拿到数值列 [历史],[数学],[英语],[语文]DECLARE @sql_col VARCHAR(8000);SELECT @sql_col = ISNULL(@sql_col + ',','') + QUOTENAME(SubjectName) FROM ScoreStatistics GROUP BY SubjectName;print(@sql_col); -- 打印数值列,不必需SET @sql_str = 'SELECT * FROM (SELECT [UserName],[SubjectName],[Score] FROM [ScoreStatistics]) p PIVOT(SUM([Score]) FOR [SubjectName] IN ( '+ @sql_col +') ) AS pvtORDER BY pvt.[UserName]'PRINT (@sql_str);--打印执行的sqlEXEC (@sql_str);-- 执行查询
输出结果
UserName 语文 数学 英语 历史
小王 100 90.5 88 65
小刘 90 85 59 98
小李 81 99 95 90


四、列转行示例

  
  
 
-- 插入测试表CREATE TABLE ScoreSummary( UserName NVARCHAR(20), --学生姓名 数学 FLOAT, --数学成绩 英语 FLOAT, --英语成绩 语文 FLOAT, --语文成绩 历史 FLOAT, --历史成绩)-- 插入测试数据INSERT INTO ScoreSummary SELECT '小李',81,99,95,90;INSERT INTO ScoreSummary SELECT '小刘',90,85,59,98;INSERT INTO ScoreSummary SELECT '小王',100,90.5,88,65;-- 查询用法select aa.UserName,aa.Scorefrom (select UserName,数学,英语,语文,历史 from dbo.ScoreSummary) as aunpivot(Score for ScoreSummary in(数学,英语,语文,历史)) as aa order by aa.UserName

输出结果

UserName Score
小李 81
小李 99
小李 95
小李 90
小刘 90
小刘 85
小刘 59
小刘 98
小王 100
小王 90.5
小王 88
小王 65

IT技术分享社区

个人博客网站:https://programmerblog.xyz

数据库:SQLServer 实现行转列、列转行用法笔记



文章推荐
SQL常用语句大全(值得收藏)
办公技巧:常用的100个Word快捷键!
GitHub上值得收藏的100个精选前端项目!
数据库优化:SQL 查找是否”存在”,别再 count 了,很耗费时间的!
学习 MySQL 高性能优化原理,这一篇就够了!
MySQL优化:数据量很大,分页查询很慢,有什么优化方案?
数据库:MySQL中,当update修改数据与原数据相同时会再次执行吗?



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/2502.html原文链接:https://javaforall.net

(0)
上一篇 2020年11月14日 上午11:06
下一篇 2020年11月14日 上午11:06


相关推荐

  • 以太网Flow Control相关

    以太网Flow Control相关pausepkt,MAC0为self-station,MAC1为link-partnerstationflow如下step1~2:MAC1向MAC0TXpkt,MAC0RX到pkt后送给后续moduleA处理。step3:MAC0来不及处理源源不断的MAC1送来的pkt,此时拉低FC_rdy(一般有RXctrl相关module起)(flowcontrolready)信号,表明此时需要进行flowcontrol;step4:MAC0TX端看到FC_rd.

    2022年6月5日
    45
  • Scrapy爬虫框架,入门案例(非常详细)「建议收藏」

    Scrapy爬虫框架,入门案例(非常详细)「建议收藏」Scrapy,Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试.其最初是为了页面抓取(更确切来说,网络抓取)所设计的,后台也应用在获取API所返回的数据(例如AmazonAssociatesWebServices)或者通用的网络爬虫.Scrapy吸引人的地…

    2022年6月26日
    29
  • tp3,nginx配置支持pathinfo

    tp3,nginx配置支持pathinfoNginx 默认是不支持 PATHINFO 的第一步 修改 server 块 server listen80 server namewww domain comdomain com error page404 404 html error page50050250 50x html 这个 locat

    2025年9月16日
    5
  • ShellExecute, WinExec, CreateProcess的使用[通俗易懂]

    ShellExecute, WinExec, CreateProcess的使用[通俗易懂]ShellExecute  ShellExecute的功能是运行一个外部程序(或者是打开一个已注册的文件、打开一个目录、打印一个文件等等),并对外部程序有一定的控制。  有几个API函数都可以实现这些功能,但是在大多数情况下ShellExecute是更多的被使用的,同时它并不是太复杂。  ShellExecute函数原型及参数含义如下:  ShellExecute(

    2022年7月27日
    6
  • Pandas库基础知识(一)

    Pandas库基础知识(一)1Series 数据结构 1 1Series 介绍 Series 是一种类似于一维数组的对象 由一组数据和一组数据标签 索引值 组成 1 2Series 的操作 1 2 1 创建 Series 对象通过 Series 方法创建对象 也可以直接将列表 字典等序列类型转换成 Series 数据 importpandas pd Series a b c d e f s2 pd Series 1 2 3 4 5 6 index a b c d

    2026年3月17日
    2
  • 浅析GPU通信技术(中)-NVLink总线协议

    浅析GPU通信技术(中)-NVLink总线协议1 背景 上一篇文章 浅析 GPU 通信技术 上 GPUDirectP2P 中我们提到通过 GPUDirectP2P 技术可以大大提升 GPU 服务器单机的 GPU 通信性能 但是受限于 PCIExpresss 总线协议以及拓扑结构的一些限制 无法做到更高的带宽 为了解决这个问题 NVIDIA 提出了 NVLink 总线协议 本篇文章我们就来谈谈 NVIDIA

    2026年3月17日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号