在许多的互联网项目当中,报表开发是整个项目当中很重要的一个功能模块。其中会有一些比较复杂的报表统计需要行转列或者列转行的需求。今天给大家简单介绍一下在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 '小王', '语文', 100
INSERT INTO ScoreStatistics SELECT '小王', '数学', 90.5
INSERT INTO ScoreStatistics SELECT '小王', '英语', 88
INSERT INTO ScoreStatistics SELECT '小王', '历史', 65
INSERT INTO ScoreStatistics SELECT '小李', '语文', 81
INSERT INTO ScoreStatistics SELECT '小李', '数学', 99
INSERT INTO ScoreStatistics SELECT '小李', '英语', 95
INSERT INTO ScoreStatistics SELECT '小李', '历史', 90
INSERT INTO ScoreStatistics SELECT '小刘', '语文', 90
INSERT INTO ScoreStatistics SELECT '小刘', '数学', 85
INSERT INTO ScoreStatistics SELECT '小刘', '英语', 59
INSERT 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 ScoreStatistics
group by UserName
-- PIVOT 写法更简洁
SELECT * FROM ScoreStatistics
AS P
PIVOT
(SUM(Score/*行转列后 列的值*/) FORp.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 pvt
ORDER BY pvt.[UserName]'
PRINT (@sql_str);--打印执行的sql
EXEC (@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

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

数据库:SQLServer 实现行转列、列转行用法笔记相关推荐

  1. 数据库查询某行 或者 某列转换为数组方法,数据库脱机原理

    十二个月包括0的也查询显示为两列数据 select m.id mon, ISNULL(b,0) InWeight from( select 1 as id union select 2 union s ...

  2. 数据库-笛卡儿积、行选择、列选择

    前排提示:个人复习的心得,部分摘抄别人的 笛卡儿积 符号表示:两个列表R,S,R×S即为笛卡儿积 行选择 符号:σ(aθb) 含义:θ为运算符,整个符号表示选择满aθb关系的所有元组(行) 例子: σ ...

  3. sqlserver中某列转成以逗号连接的字符串及逆转、数据行转列列转行

    Sql Server 列转逗号隔开的字符串 和 逆转 https://www.cnblogs.com/duanyuerui/p/7567692.html Sql server 中将数据行转列列转行(一 ...

  4. greenplum 数据库如何增加列_Greenplum行存与列存的选择以及转换方法-阿里云开发者社区...

    背景 数据在数据库中的存储形式多种多样,比较常见的如 1. PostgreSQL的堆表,以行的形式存储,(当变成字段压缩后的长度超过数据块的四分之一时,会以TOAST的形式存储到TOAST表). 2. ...

  5. SQL Server 行转列,列转行。多行转成一列

    一.多行转成一列(并以","隔开) 表名:A 表数据: 想要的查询结果: 查询语句: SELECT name ,value = ( STUFF(( SELECT ',' + val ...

  6. 数据库的方向 - 行vs列(转自: IBM i 中国开发团队)

    转载地址:https://www.ibm.com/developerworks/community/blogs/IBMi/entry/database?lang=en 原文链接:http://ibms ...

  7. 聊一聊数据库的行存与列存

    目录 存储方式比较 优缺点比较 行存与列存实验 选择建议 注意事项 好多人最开始学习数据库的时候,是关系数据库,数据以表格形式存储,一行表示一条记录.其实这种就是典型的行存储(Row-based st ...

  8. 【大数据技术基础系列】列式数据库与基于行的数据库存储数据结构

    目录 列式数据库与基于行的数据库 基于行的数据库系统物理结构布局

  9. Hive(行转列 列转行)

    Hive(行转列 列转行) 行转列 行专列常用的几种方式有 collect_list collect_set 举例说明 原数据 sql SELECT concat_ws("|",c ...

最新文章

  1. python使用界面-推荐8款常用的Python GUI图形界面开发框架
  2. 帝国php.ini路径,帝国CMS数据库配置文件是哪个文件?
  3. poj3685 二分套二分
  4. 对.NET Core未来发展趋势的浅层判断
  5. mysql自增id用完了_MySQL表自增id用完了该怎么办?
  6. html iframe php,html iframe使用的实战总结分享
  7. 查看宝塔面板账号密码命令_宝塔面板升级到最新版图文教程
  8. Oracle中临时表的深入研究
  9. php获取表所有数据类型,php excel 导入 导入三级分类 表格应该怎么设计才能得到想要的数据格式?...
  10. 600个开源iOS应用库
  11. 谷歌开放语音识别 API,发力人工智能
  12. Linux中select函数的使用 select() Linux linux函数 select
  13. eclipse jad 反编译class文件 插件安装
  14. LDC注册数据获取|ACE2004, ACE 2005,OntoNotes等数据
  15. 在bug的边缘疯狂试探之mybatis
  16. 面试被问离职原因,别乱说
  17. 《汇编语言》学习笔记
  18. 【原创】harvey指导soc裸机程序文件头等制作_Detective_ALong_新浪博客
  19. Ubuntu下VScode配置ssh免密远程登录
  20. element组件------form

热门文章

  1. 微软2008系列 (Orcas + Longhorn Server+SQL2008)将于2008年2月27日发布
  2. 给自己的Blog 上添加定制的搜索引擎
  3. windows下安装python和Python-opencv
  4. 【文件处理】——字典写入json文件或TXT文件,读取文件中的字典TypeError: Object of type ‘ndarray‘ is not JSON serializable错误解决方法
  5. 【图像处理】——Python图像分割边缘检测算法之二阶梯度算子(laplace、log、dog算子)
  6. c语言输出去掉最后一行回车,新人提问:如何将输出时每行最后一个空格删除...
  7. Android零基础入门第81节:Activity数据传递
  8. 请求转发和请求重定向的区别?
  9. WPF之无法触发KeyDown或者KeyUp键盘事件
  10. 用 PS 调整服务器时间