老生常谈之SQL Server (行转列,列转行)
Open the first article
在本文章中主要介绍以下内容:
- 1、静态行转列
- 2、静态列转行
- 3、动态行转列
- 4、动态列转行
1、静态行转列
--静态的行转列
--新建一个科目成绩表
--三个字段:学生名称,科目,成绩
CREATE TABLE SubjectScore
(
StuName nvarchar(20),
SubjectName nvarchar(20),
Fraction decimal(16,2)
) --插入4条数据
INSERT INTO SubjectScore
VALUES(N'孔子',N'语文',99) INSERT INTO SubjectScore
VALUES(N'孔子',N'数学',80) INSERT INTO SubjectScore
VALUES(N'诸葛',N'语文',75.5) INSERT INTO SubjectScore
VALUES(N'诸葛',N'数学',66) --行转列
SELECT StuName,
ISNULL(SUM(case SubjectName when N'语文' then isnull(Fraction,0)end),0)as N'语文',
ISNULL(SUM(case SubjectName when N'数学' then isnull(Fraction,0)end),0)as N'数学'
FROM SubjectScore
GROUP BY StuName --如果加了个英语科目怎么办?没错,代码要改
--下面我们加个英文科目
INSERT INTO SubjectScore
VALUES(N'诸葛',N'英语',66) --修改代码后行转列
SELECT StuName,
ISNULL(SUM(case SubjectName when N'语文' then isnull(Fraction,0)end),0)as N'语文',
ISNULL(SUM(case SubjectName when N'数学' then isnull(Fraction,0)end),0)as N'数学',
ISNULL(SUM(case SubjectName when N'英语' then isnull(Fraction,0)end),0)as N'英语'
FROM SubjectScore
GROUP BY StuName
结果:
2、静态列转行
--静态列转行
--表结构:我们建几个中文的字段:学生名称,语文,数学
CREATE TABLE Demo_Stu
(
学生名称 nvarchar(20),
语文 decimal(16,2),
数学 decimal(16,2)
) --一样插入4条数据
INSERT INTO Demo_Stu
VALUES(N'孔子',88,99) INSERT INTO Demo_Stu
VALUES(N'孔子',99,69) INSERT INTO Demo_Stu
VALUES(N'诸葛',88,55) INSERT INTO Demo_Stu
VALUES(N'诸葛',77,63) --我们可以用union all 来实现,
--不了解 union all怎么用的兄弟请自行百度
select * from (
select 学生名称 as StuName,Subject=N'语文',Fraction=语文 from Demo_Stu
union all
select 学生名称 as StuName,Subject=N'数学',Fraction=数学 from Demo_Stu
)p order by StuName
结果:
3、动态行转列
--动态的行转列
--科目成绩表
--三个字段:学生名称,科目,成绩
CREATE TABLE SubjectScore
(
StuName nvarchar(20),
SubjectName nvarchar(20),
Fraction decimal(16,2)
) --插入4条数据
INSERT INTO SubjectScore
VALUES(N'孔子',N'语文',99) INSERT INTO SubjectScore
VALUES(N'孔子',N'数学',80) INSERT INTO SubjectScore
VALUES(N'诸葛',N'语文',75.5) INSERT INTO SubjectScore
VALUES(N'诸葛',N'数学',66) /*
动态行转列我们主要用到以下几个关键函数:
2.PIVOT
1.QUOTENAME
*/
DECLARE @sql_col NVARCHAR(4000)
DECLARE @sql_str NVARCHAR(4000)
/*取表中行转列的所有科目*/
SELECT @sql_col = ISNULL(@sql_col+',','')+QUOTENAME(SubjectName) FROM SubjectScore GROUP BY SubjectName
SET @sql_str = '
SELECT * FROM SubjectScore p PIVOT(
SUM([Fraction]) FOR [SubjectName] IN('+@sql_col+')
) pvt
order by StuName
'
EXEC (@sql_str) --如果加了个英语科目怎么办?代码不需要改动
--下面我们加个历史科目,再执行上面的行转列代码
INSERT INTO SubjectScore
VALUES(N'诸葛',N'历史',88) INSERT INTO SubjectScore
VALUES(N'孔子',N'历史',99)
结果:
4、动态列转行
--动态态列转行
--表结构:我们建几个中文的字段:学生名称,语文,数学
CREATE TABLE Demo_Stu
(
学生名称 nvarchar(20),
语文 decimal(16,2),
数学 decimal(16,2)
) --一样插入4条数据
INSERT INTO Demo_Stu
VALUES(N'孔子',88,99) INSERT INTO Demo_Stu
VALUES(N'孔子',99,69) INSERT INTO Demo_Stu
VALUES(N'诸葛',88,55) INSERT INTO Demo_Stu
VALUES(N'诸葛',77,63) --列传行
--列转行的方案来源于:Joe.TJ
--列转行的动态方案:UNPIVOT,sql2005及以后版本
--因为行是动态所以这里就从INFORMATION_SCHEMA.COLUMNS视图中获取列来构造行,同样也使用了XML处理。
DECLARE @SQL NVARCHAR(4000)=N'';
SET @SQL=STUFF((SELECT N','+QUOTENAME(COLUMN_NAME ) FROM INFORMATION_SCHEMA.COLUMNS
WHERE ORDINAL_POSITION>1 AND TABLE_NAME='Demo_Stu' FOR XML PATH('')),1,1,N'')
SET @SQL=N'SELECT *
from dbo.Demo_Stu
unpivot(分数 for 科目 in('+@SQL+'))as up';
EXEC SP_EXECUTESQL @SQL;
总结:
无论是静态的行转列或列转行都是会增加代码的维护性。
建议使用动态的行转列和列转行,可减少代码的维护性,多留一手也是比较好的。
老生常谈之SQL Server (行转列,列转行)的更多相关文章
- SQL Server自动化运维系列——关于邮件通知那点事(.Net开发人员的福利)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 邮件作为一种非常便利的预警实现方式,在及时性和易用性 ...
- SQL Server中的标识列
一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列. 该种列具有以下三种特点: .列的数据类型为不带小数的数值类型 .在进行插入(Insert)操作时,该列的值是由 ...
- SQL Server 2016:内存列存储索引
作者 Jonathan Allen,译者 谢丽 SQL Server 2016的一项新特性是可以在“内存优化表(Memory Optimized Table)”上添加“列存储索引(Columnstor ...
- SQL Server ->> ColumnStore Index(列存储索引)
Columnstored index是SQL Server 2012后加入的重大特性,数据不再以heap或者B Tree的形式存储(row level)存储在每一个数据库文件的页里面,而是以列为单位存 ...
- Sql Server中的标识列(自增长字段)
一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列.该种列具有以下三种特点: 1.列的数据类型为不带小数的数值类型2.在进行插入(Insert)操作时,该列的值是由 ...
- SQL Server自动化运维系列——监控跑批Job运行状态(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在上一篇文章中已经分析了SQL SERVER中关于邮 ...
- SQL SERVER将某一列字段中的某个值替换为其他的值 分类: MSSQL 2014-11-05 13:11 67人阅读 评论(0) 收藏
SQL SERVER将某一列字段中的某个值替换为其他的值 UPDATE 表名 SET 列名 = REPLACE(列名 ,'贷','袋') SQL SERVER"函数 replace 的参数 ...
- SQL Server 行转列重温
转载自http://www.cnblogs.com/kerrycode/ 行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER ...
- 【转载】SQL Server行转列,列转行
行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现.用传统的方法,比较好理解.层次清 ...
- Sql Server 行转列
--摘自百度 PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (… ...
随机推荐
- 安装xampp出错,安装xampp出错,windows找不到-n ?
安装路径错误的问题 安装参考路径:D:\xampp\子文件
- Vulkan Tutorial 20 Vertex buffer creation
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 在Vulkan中,缓冲区是内存的一块区域,该区域用于向显卡 ...
- c++,函数名不要和某个类名相同 (syntax error : missing ';' before identifier....)
直接上代码: // outside.h class Outside { private: class Inner { public: Inner(Outside& out) : out_(ou ...
- Redis中的数据对象
redis对象 redis中有五种常用对象 我们所说的对象的类型大多是值的类型,键的类型大多是字符串对象,值得类型大概有以下几种,但是无论哪种都是基于redisObject实现的 redisObjec ...
- Spring中多个工程停多个资源文件ignoreUnresolvablePlaceholders配置
http://www.imooo.com/ruanjiangongcheng/software-architecture-design/667686.htm
- URL重定向
/** * URL重定向 * @param string $url 重定向的URL地址 * @param integer $time 重定向的等待时间(秒) * @param string $msg ...
- php通过cURL下载网络上面的一个HTTPS的资源
<?php /** * php通过cURL下载网络上面的一个HTTPS的资源 * 案例:从google的CDN上下载jquery- v1.7.1 */ $curlobj = curl_init( ...
- 移动端布局,C3新增属性
<html5拖拽> 1.给元素设置 draggable="true" 属性,这个元素就可以被拖拽了 <拖拽元素事件> 2.ondragstart 拖拽前触发 ...
- MySQL数据库Raid存储方案
作为一名DBA,选择自己的数据存储在什么上面,应该是最基本的事情了.但是很多DBA却容易忽略了这一点,我就是其中一个.之前对raid了解的并不多,本文就记录下学习的raid相关知识. 一.RAID的基 ...
- JavaWeb 后端 <十一> 之 DBUtils 框架 (基本使用 结果集 事务处理 对表读取)
一.数据库操作框架 1.ORM:Object Relation Mapping Hibernate:非常流行 JPA:Java Persistent API.ORM标准 MyBatis:2010年开始 ...