sql server 纵横表的转换
在平常的工作中或者面试中,我们可能有遇到过数据库的纵横表的转换问题。今天我们就来讨论下。
1.创建表
首先我们来创建一张表。
sql语句:
--1. 创建数据表
if OBJECT_ID('Score') is not null drop table Score create table Score
(
姓名 nvarchar(128),
课程 nvarchar(128),
分数 int
) insert into Score values('张三','语文',98)
insert into Score values('张三','数学',89)
insert into Score values('张三','物理',78)
insert into Score values('李四','语文',79)
insert into Score values('李四','数学',88)
insert into Score values('李四','物理',100) select * from Score
执行结果:
2. 传统的纵横表转换
2.1 纵表转横表
先看看我们要转成的横表张什么样子:
既然这个表只有两列,那么可以根据姓名进行分组。先把姓名拼凑出来,后面的分数我们再想办法。
sql:
select t.姓名 2 from Score as t 3 group by t.姓名
结果:
分析:
- 我们先拿到语文这个科目的分数。既然我们用到了group by 语句,这里肯定要用聚合函数来求分数。
- 而且我们只需要语文这一科的成绩,分组出来的 一共有 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 中。
-- 转换的表插入新表
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 物理
into ScoreHb
from Score as t
group by t.姓名
这时ScoreHb 就是我们刚转换好的横表,我们再想办法把他转回来。
怎么转呢? 一步步来。我们也先把张三和李四的语文成绩查出来。
sql:
--张三李四语文的分数
select t.姓名,
'语文' as 课程,
t.语文 as 分数
from ScoreHb as t
结果:
还有两科的数据怎么办呢? 很简单,我们一个个都查出来,然后用 union all 把他们组合为一张表就可以了。
sql:
-- union all链接3个科目
select t.姓名,
'语文' as 课程,
t.语文 as 分数
from ScoreHb as t
union all
select t.姓名,
'数学' as 课程,
t.数学 as 分数
from ScoreHb as t
union all
select t.姓名,
'物理' as 课程,
t.物理 as 分数
from ScoreHb as t
order by t.姓名 desc
结果:
这样,我们就把表又变回去了。
但是大家有没有觉得很麻烦呢?别急,我们有更简单的办法。下面为大家介绍pivot关系运算符。
3. 用pivot和unpivot运算符进行转换
pivot是sql server 2005 提供的运算符,所以只要数据库在05版本以上的都可以使用。主要用于行和列的转换。
3.1 pivot纵表转横表
sql:
select
t2.姓名,
t2.数学,
t2.物理,
t2.语文
from Score as t1
pivot (sum(分数) for 课程 in(数学,语文,物理)) as t2
结果:
是不是代码简洁多了。
pivot将原来表中 课程字段中的 数据行 数学,语文,物理 转换为列,并用sum取对应列的值。
我们只需要记住它的用法就可以了。
3.2 unpivot 横表转纵表
既然有privot可以纵表转横表。那么有没有运算符帮我们转回来呢?
答案是肯定的,他就是unpivot
sql:
select
*
from
ScoreHb
unpivot (分数 for 课程 in (语文,数学,物理)) as t4
结果:
unpivot 将 语文,数学,物理 列转为行,分数为新的一列存放对应的值。
是不是比我们之前一个个表查询拼接,方便了很多。
sql server 纵横表的转换的更多相关文章
- sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)
sql server 关于表中只增标识问题 由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错 ...
- SQL Server创建表超出行最大限制解决方法
问题的现象在创建表A的时候,出现“信息 511,级别 16,状态 1,第 5 行 无法创建大小为 的行,该值大于允许的最大值 8060.”的信息提示.很奇怪,网上查了一下,是因为要插入表的数据类型的 ...
- SQL Server日期时间格式转换字符串详解 (详询请加qq:2085920154)
在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的.本文我们主要就介绍一下SQL Server日 ...
- SQL Server日期时间格式转换字符串
在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的.本文我们主要就介绍一下SQL Server日 ...
- 千万级SQL Server数据库表分区的实现
千万级SQL Server数据库表分区的实现 2010-09-10 13:37 佚名 数据库 字号:T | T 一般在千万级的数据压力下,分区是一种比较好的提升性能方法.本文将介绍SQL Server ...
- Azure 意外重启, 丢失sql server master表和 filezilla
突然发现今晚网站打不开了,提示连不上数据库. ftp也连不上了. 远程连上Azure 发现机器意外重启, 丢失sql server master表和 filezilla 要重新安装. 又耗费我几个小时 ...
- SQL Server 系统表简介
SQL Server 系统表简介 系统目录是由描述SQL Server 系统的数据库.基表.视图和索引等对象的结构的系统表组成.SQL Server 经常访问系统目录,检索系统正常运行所需的必要信息. ...
- [SQL]SQL Server数据表的基础知识与增查删改
SQL Server数据表的基础知识与增查删改 由张晨辉(学生) 于19天 前发表 | 阅读94次 一.常用数据类型 .整型:bigint.int.smallint.tinyint .小数:decim ...
- SQL Server 锁表、查询被锁表、解锁相关语句
SQL Server 锁表.查询被锁表.解锁相关语句,供参考. --锁表(其它事务不能读.更新.删除) BEGIN TRAN SELECT * FROM <表名> WITH(TABLOCK ...
随机推荐
- 怎样在不对控件类型进行硬编码的情况下在 C#vs 中动态添加控件
文章ID: 815780 最近更新: 2004-1-12 这篇文章中的信息适用于: Microsoft Visual C# .NET 2003 标准版 Microsoft Visual C# .NET ...
- Java基础教程:泛型基础
Java基础教程:泛型基础 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚 ...
- oracle扩容
动态添加表空间: alter tablespace cbs_cos add datafile '/dba/oradata/ORADEVdatafile/cbs_cos02.dbf' size 100m ...
- 建议10:numpy使用基础
# -*- coding: utf-8 -*- import numpy as np #---------------------------------------- #-- 定义 ndarray ...
- JS兼容各个浏览器的本地图片上传即时预览效果\、
在firefox\chrome\ie10等浏览器中可以使用HTML5中的内容实现图片即时预览效果,在IE10以下浏览器中使用滤镜来解决图片显示问题. HTML5中的FileReader对象主要是把文件 ...
- 20145240 《Java程序设计》第一次实验报告
20145240 <Java程序设计>第一次实验报告 实验内容 一.命令行下java程序开发 1.建立Code目录,输入mkdir 20145240命令建立实验目录,并使用dir命令查看目 ...
- linux下安装编译网卡驱动的方法
安装linux操作系统后发现没有网卡驱动,表现为 system → Administration → Network下Hardware列表为空. 以下为安装编译网卡驱动的过程,本人是菜鸟,以下是我从网 ...
- maven 安装、运行、获取帮助 —— maven权威指南学习笔记(二)
这部分在网上很容易找到详细教程,这里就略写了. 基础:系统有配置好的jdk,通过 命令行 java -version,有类似下面的提示,表示java环境以配好 下载maven:官网 http://ma ...
- HDFS请求接口
通过HTTP来访问HDFS有两种方法:直接访问,HDFS后台进程直接服务于来自客户端的请求:通过代理(一对多)访问,客户端通常使用DistributedFileSystemAPI访问HDFS.第一种情 ...
- Caused by: org.apache.ibatis.binding.BindingException: Parameter 'parameter' not found.解决
Caused by: org.apache.ibatis.binding.BindingException: Parameter 'company' not found. Available para ...