在平常的工作中或者面试中,我们可能有遇到过数据库的纵横表的转换问题。今天我们就来讨论下。

1.创建表

  首先我们来创建一张表。

sql语句:

 1 --1. 创建数据表
 2 if OBJECT_ID('Score') is not null drop table Score
 3
 4 create table Score
 5 (
 6     姓名 nvarchar(128),
 7     课程 nvarchar(128),
 8     分数 int
 9 )
10
11 insert into Score values('张三','语文',98)
12 insert into Score values('张三','数学',89)
13 insert into Score values('张三','物理',78)
14 insert into Score values('李四','语文',79)
15 insert into Score values('李四','数学',88)
16 insert into Score values('李四','物理',100)
17
18 select * from Score

执行结果:

2. 传统的纵横表转换

2.1 纵表转横表

先看看我们要转成的横表张什么样子:

既然这个表只有两列,那么可以根据姓名进行分组。先把姓名拼凑出来,后面的分数我们再想办法。

sql:

select t.姓名 2 from Score as t 3 group by t.姓名 

结果:

分析:

  1. 我们先拿到语文这个科目的分数。既然我们用到了group by 语句,这里肯定要用聚合函数来求分数。
  2. 而且我们只需要语文这一科的成绩,分组出来的 一共有 3列 ,分别是 语文、数学、物理  。  那么就需要判断科目来取分数。

这里符合我们需求的 case 语句就登场了。他和c#中switch-case 作用一样。

sql case 语句语法:

case 字段when 值1 then 结果when 值2 then 结果2...else 默认结果
end 

求语文的分数就简单了:

select t.姓名,
SUM(case t.课程 when '语文' then t.分数 else 0 end) as 语文
from Score as t
group by t.姓名

结果:

既然语文的分数取到了,其他科目改变下条件就可以了。

完整的sql:

select t.姓名,
SUM(case t.课程 when '语文' then t.分数 else 0 end) as 语文,
SUM(case t.课程 when '数学' then t.分数 else 0 end) as 数学,
SUM(case t.课程 when '物理' then t.分数 else 0 end) as 物理
from Score as t
group by t.姓名

OK,到这儿,我们传统方式的纵表转横表就大功告成了。

2.2 横表转纵表

那么我们可以把转换过来的横表再转换回去吗?

我们先把刚刚转好的表,插入一个新表ScoreHb 中。

1 -- 转换的表插入新表
2 select t.姓名,
3 SUM(case t.课程 when '语文' then t.分数 else 0 end) as 语文,
4 SUM(case t.课程 when '数学' then t.分数 else 0 end) as 数学,
5 SUM(case t.课程 when '物理' then t.分数 else 0 end) as 物理
6 into ScoreHb
7 from Score as t
8 group by t.姓名

这时ScoreHb 就是我们刚转换好的横表,我们再想办法把他转回来。

怎么转呢? 一步步来。我们也先把张三和李四的语文成绩查出来。

sql:

1 --张三李四语文的分数
2 select t.姓名,
3 '语文' as 课程,
4 t.语文 as 分数
5 from ScoreHb as t

结果:

还有两科的数据怎么办呢? 很简单,我们一个个都查出来,然后用 union all 把他们组合为一张表就可以了。

sql:

 1 -- union all链接3个科目
 2 select t.姓名,
 3 '语文' as 课程,
 4 t.语文 as 分数
 5 from ScoreHb as t
 6 union all
 7 select t.姓名,
 8 '数学' as 课程,
 9 t.数学 as 分数
10 from ScoreHb as t
11 union all
12 select t.姓名,
13 '物理' as 课程,
14 t.物理 as 分数
15 from ScoreHb as t
16 order by t.姓名 desc

结果:

这样,我们就把表又变回去了。

但是大家有没有觉得很麻烦呢?别急,我们有更简单的办法。下面为大家介绍pivot关系运算符。

3. 用pivot和unpivot运算符进行转换

  pivot是sql server 2005 提供的运算符,所以只要数据库在05版本以上的都可以使用。主要用于行和列的转换。

3.1 pivot纵表转横表

sql:

1 select
2     t2.姓名,
3     t2.数学,
4     t2.物理,
5     t2.语文
6 from Score as t1
7 pivot (sum(分数) for 课程 in(数学,语文,物理)) as t2

结果:

是不是代码简洁多了。

pivot将原来表中 课程字段中的 数据行 数学,语文,物理 转换为列,并用sum取对应列的值。

我们只需要记住它的用法就可以了。

3.2 unpivot 横表转纵表

既然有privot可以纵表转横表。那么有没有运算符帮我们转回来呢?

答案是肯定的,他就是unpivot

sql:

1 select
2     *
3 from
4 ScoreHb
5 unpivot (分数 for 课程 in (语文,数学,物理)) as t4

结果:

 unpivot 将 语文,数学,物理 列转为行,分数为新的一列存放对应的值。

是不是比我们之前一个个表查询拼接,方便了很多。

转载于:https://www.cnblogs.com/simple-blog/p/4371240.html

sql server 纵横表的转换相关推荐

  1. php多表查询性能优化,MSSQL_SQL Server多表查询优化方案集锦,SQL Server多表查询的优化方案是 - phpStudy...

    SQL Server多表查询优化方案集锦 SQL Server多表查询的优化方案是本文我们主要要介绍的内容,本文我们给出了优化方案和具体的优化实例,接下来就让我们一起来了解一下这部分内容. 1.执行路 ...

  2. Access和SQL server开启表间关系,并实现更新或删除母表数据自动更新或删除子表数据...

    1.Access开启表间关系,并实现删除母表数据自动删除子表数据: 在Tables等界面 - > 右键 - > Relationships... -> 弹出Relationships ...

  3. SQL Server日期格式的转换

    SQL Server日期格式的转换 [原创 2007-03-23 09:34:36]     字号: 大 中 小 SQL Server中文版的默认的日期字段datetime格式是yyyy-mm-dd ...

  4. columnproperty server sql_导出SQL Server数据库表中字段的说明/备注

    时 间:2013-02-18 09:09:11 作 者:摘 要:导出SQL Server数据库表中字段的说明/备注 正 文: 打开SQL企业管理器 ,找到你要导出用户表字段信息的那个数据库 ,点击工具 ...

  5. SQL Server修改表结构后批量更新所有视图

    --获取指定SQLServer数据库所有表及视图的字段列表及类型.长度 Select o.Name As ObjectsName , c.name As ColumnsName , t.name As ...

  6. SQL Server 将一个表中字段的值复制到另一个表的字段中

    原文:SQL Server 将一个表中字段的值复制到另一个表的字段中 具体方法如下 一:update 表2 set (要插入的列名)= select 表1.某一列 from 表1 left jion ...

  7. php从注册列表卸载,MSSQL_彻底删除SQL Server注册表的方法,一般在卸载完数据库时,大家 - phpStudy...

    彻底删除SQL Server注册表的方法 一般在卸载完数据库时,大家都希望能够将注册表信息完全删干净,下面就将教您彻底删除SQL Server注册表的方法,供您参考. 在卸载SQL Server开始- ...

  8. sql server复制表_具有超过246列的表SQL Server复制

    sql server复制表 问题 (Problem) In our environment we use SQL Server merge replication to replicate data ...

  9. 利用T-SQL处理SQL Server数据库表中的重复行

    Duplicate rows in a SQL Server database table can become a problem. We will see how we can find and ...

最新文章

  1. 程序员的生活就是这么朴实无华,且没钱
  2. 计算机配置中无可移动设备访问,USB连接正常,但是我的电脑中不显示可移动 – 手机爱问...
  3. 深度剖析 | 阿里热修复如何精简优化补丁资源?
  4. CSS实现导航条Tab切换的三种方法
  5. 这些元器件基础知识都不懂,怎么混电子圈!
  6. 此处不允许使用分组函数_Excel中使用Vlookup函数实现数据分组
  7. matlab与STK互联(不使用connect软件的互联)
  8. 【Docker】Mac下Docker启动Kubernetes
  9. 一步一步从Linux线程到MySQL慢sql定位
  10. python 匿名函数装饰器
  11. [js开源组件开发]js文本框计数组件
  12. python c++ socket 通信一个示例
  13. sniffer辅助功能详解
  14. JDK自带的java.util.Timer定时器的实现原理
  15. [C/C++] C++中new的语法规则
  16. drupal简体中文语言包安装方法
  17. iOS功能测试工具 Frank
  18. gke google_使用ExternalDNS扩展GKE
  19. 如何制作好看的菜单c语言,一种漂亮的自绘菜单
  20. 笔记本同时内外网双网网卡上网(网线不能连外网,wifi可以连外网)

热门文章

  1. mysql命令 show_mysql show 相关命令
  2. python2.7对DICOM图像的读取
  3. mybatis generator 中文注释_[SpringBoot2.X] 23- 整合持久层技术 -MyBatis - 配置
  4. 系统学习数字图像处理之形态学分析
  5. 2012.4.17总结(一)
  6. Hbase namespace操作入门
  7. scala zip--拉链操作入门
  8. Opencv_HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP解决方案
  9. Const限定符与C++11Constexpr的区别
  10. 常见数据结构总结,持续更新...